feat: 点云数据新增俯视图查看&首页告警数据统计调整

dev
donghao 2 days ago
parent dfa0eafb16
commit d8c58dd183

Binary file not shown.

After

Width:  |  Height:  |  Size: 642 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 497 B

@ -38,16 +38,11 @@ const colorArr = [
["#3B9FFE", "#5070F2"], ["#3B9FFE", "#5070F2"],
["#FFDA8D", "#FFAC06"], ["#FFDA8D", "#FFAC06"],
]; ];
const deviceStatus = ref({
onlineCount: 50,
errorCount: 10,
outlineCount: 10,
});
const searchForm = reactive({ const searchForm = reactive({
car: "1", car: "1",
pole: "1", pole: "1",
}); });
const deviceTotal = ref(0);
const carFaultTotal = ref([]); const carFaultTotal = ref([]);
const poleFaultTotal = ref([]); const poleFaultTotal = ref([]);
@ -56,36 +51,284 @@ const activeBtn = ref("month");
const isAlarmOpen = ref<Boolean>(false); // const isAlarmOpen = ref<Boolean>(false); //
const currentRow = ref<Record<string, any>>({}); // const currentRow = ref<Record<string, any>>({}); //
const currFileList = ref<Record<string, any>[]>([]); // const currFileList = ref<Record<string, any>[]>([]); //
const deviceInfo = reactive({
list: [ const deviceInfo = ref({
{ total: 0,
name: "车体检测设备", onlineCount: 0,
bindVal: { errorCount: 0,
total: 0, outlineCount: 0,
},
icon: car_device_icon,
},
// {
// name: "",
// bindVal: {
// total: 0,
// },
// icon: pole_device_icon,
// },
// {
// name: "",
// bindVal: {
// total: 0,
// },
// icon: excavator_device_icon,
// },
],
}); });
const trainListData = ref([ const trainListData = ref([
{ {
arrive_img_url:
"http://192.168.10.14:8123/sftp/2025-07-01/20250701_131010.jpg",
created_at: "2023-10-01 10:00:00", created_at: "2023-10-01 10:00:00",
device_position: "车体检测设备", device_position: "车体检测设备",
data: {
train_data: [
{
model: "C54K",
carriage_number: "01-48937",
},
{
model: "C54K",
carriage_number: "01-34895",
},
{
model: "C54K",
carriage_number: "00-50912",
},
{
model: "C54K",
carriage_number: "02-18734",
},
{
model: "C54K",
carriage_number: "04-99681",
},
{
model: "C54K",
carriage_number: "04-71120",
},
{
model: "C54K",
carriage_number: "04-50236",
},
{
model: "C54K",
carriage_number: "02-17084",
},
{
model: "C54K",
carriage_number: "00-12068",
},
{
model: "C54K",
carriage_number: "00-26203",
},
{
model: "C54K",
carriage_number: "00-67639",
},
{
model: "C54K",
carriage_number: "01-31401",
},
{
model: "C54K",
carriage_number: "00-33740",
},
{
model: "C54K",
carriage_number: "01-74883",
},
{
model: "C54K",
carriage_number: "02-32217",
},
{
model: "C54K",
carriage_number: "00-52434",
},
{
model: "C54K",
carriage_number: "02-32892",
},
{
model: "C54K",
carriage_number: "03-82204",
},
{
model: "C54K",
carriage_number: "04-20857",
},
{
model: "C54K",
carriage_number: "03-14256",
},
{
model: "C54K",
carriage_number: "03-28256",
},
{
model: "C54K",
carriage_number: "02-27349",
},
{
model: "C54K",
carriage_number: "02-49452",
},
{
model: "C54K",
carriage_number: "01-37996",
},
{
model: "C54K",
carriage_number: "02-81300",
},
{
model: "C54K",
carriage_number: "01-37644",
},
{
model: "C54K",
carriage_number: "03-66450",
},
{
model: "C54K",
carriage_number: "04-17540",
},
{
model: "C54K",
carriage_number: "00-83994",
},
{
model: "C54K",
carriage_number: "03-13204",
},
{
model: "C54K",
carriage_number: "00-67918",
},
{
model: "C54K",
carriage_number: "00-26850",
},
{
model: "C54K",
carriage_number: "03-28183",
},
{
model: "C54K",
carriage_number: "00-85336",
},
{
model: "C54K",
carriage_number: "02-32747",
},
{
model: "C54K",
carriage_number: "01-89385",
},
{
model: "C54K",
carriage_number: "01-97885",
},
{
model: "C54K",
carriage_number: "04-79829",
},
{
model: "C54K",
carriage_number: "00-27585",
},
{
model: "C54K",
carriage_number: "03-56310",
},
{
model: "C54K",
carriage_number: "02-62317",
},
{
model: "C54K",
carriage_number: "01-55888",
},
{
model: "C54K",
carriage_number: "04-32385",
},
{
model: "C54K",
carriage_number: "01-75685",
},
{
model: "C54K",
carriage_number: "03-45210",
},
{
model: "C54K",
carriage_number: "01-35511",
},
{
model: "C54K",
carriage_number: "00-30912",
},
{
model: "C54K",
carriage_number: "03-61047",
},
{
model: "C54K",
carriage_number: "00-24265",
},
{
model: "C54K",
carriage_number: "01-24135",
},
{
model: "C54K",
carriage_number: "00-16077",
},
{
model: "C54K",
carriage_number: "01-75557",
},
{
model: "C54K",
carriage_number: "03-81207",
},
{
model: "C54K",
carriage_number: "04-17201",
},
{
model: "C54K",
carriage_number: "03-22895",
},
{
model: "C54K",
carriage_number: "00-20144",
},
{
model: "C54K",
carriage_number: "01-37853",
},
{
model: "C54K",
carriage_number: "01-19641",
},
{
model: "C54K",
carriage_number: "04-66344",
},
{
model: "C54K",
carriage_number: "01-79470",
},
{
model: "C54K",
carriage_number: "04-39271",
},
{
model: "C54K",
carriage_number: "02-35471",
},
{
model: "C54K",
carriage_number: "03-54817",
},
{
model: "C54K",
carriage_number: "03-43384",
},
{
model: "C54K",
carriage_number: "02-41045",
},
],
},
}, },
{ {
created_at: "2023-10-01 10:00:00", created_at: "2023-10-01 10:00:00",
@ -151,6 +394,7 @@ const trainColumns = [
}, },
]; ];
const isTrainOpen = ref<Boolean>(false); // const isTrainOpen = ref<Boolean>(false); //
const currentTrainRow = ref<Record<string, any>>({}); // const currentTrainRow = ref<Record<string, any>>({}); //
const openTrainDetail = (row: record<string, any>) => { const openTrainDetail = (row: record<string, any>) => {
@ -197,24 +441,21 @@ const getDeviceInfo = async () => {
const res = await getDeviceInfowApi(); const res = await getDeviceInfowApi();
if (isSuccessApi(res)) { if (isSuccessApi(res)) {
const { data } = res; const { data } = res;
deviceTotal.value = data.deviceTotal; deviceInfo.value = {
deviceInfo.list = [ onlineCount:
{ data?.pole?.onlineCount +
name: "车体检测设备", data?.appearance?.outlineCount +
bindVal: data?.appearance, data?.excavator?.errorCount,
icon: car_device_icon, errorCount:
}, data?.pole?.errorCount +
// { data?.appearance?.errorCount +
// name: "", data?.excavator?.errorCount,
// bindVal: data?.pole, outlineCount:
// icon: pole_device_icon, data?.pole?.outlineCount +
// }, data?.appearance?.outlineCount +
// { data?.excavator?.outlineCount,
// name: "", total: data?.deviceTotal,
// bindVal: data?.excavator, };
// icon: excavator_device_icon,
// },
];
} }
} catch (error) { } catch (error) {
console.error("获取设备信息出错:", error); console.error("获取设备信息出错:", error);
@ -230,7 +471,6 @@ const fetchPoleMonitorData = async () => {
if (isSuccessApi(res)) { if (isSuccessApi(res)) {
const { data } = res; const { data } = res;
poleFaultTotal.value = data; poleFaultTotal.value = data;
// deviceStatus.value = data
console.log(data); console.log(data);
} }
} catch (error) { } catch (error) {
@ -248,7 +488,6 @@ const fetchTrainMonitorData = async () => {
if (isSuccessApi(res)) { if (isSuccessApi(res)) {
const { data } = res; const { data } = res;
carFaultTotal.value = data; carFaultTotal.value = data;
// deviceStatus.value = data
console.log(data); console.log(data);
} }
} catch (error) { } catch (error) {
@ -265,7 +504,6 @@ const getRealTime = async () => {
// TODO 使 // TODO 使
imageFault.value = data.concat(data).concat(data).splice(0, 4); imageFault.value = data.concat(data).concat(data).splice(0, 4);
} }
// deviceStatus.value = data
console.log(data); console.log(data);
} }
} catch (error) { } catch (error) {
@ -409,23 +647,14 @@ onMounted(() => {
<div class="device-total-icon mt-[24px]"></div> <div class="device-total-icon mt-[24px]"></div>
<div class="device-count ml-[24px]"> <div class="device-count ml-[24px]">
<div class="fg-mark1 text-[32px] font-bold"> <div class="fg-mark1 text-[32px] font-bold">
{{ deviceTotal }} {{ deviceInfo?.total }}
</div> </div>
<div class="text-[14px]">设备总数</div> <div class="text-[14px]">设备总数</div>
</div> </div>
</div> </div>
<ul class="device-list"> <ul class="device-list">
<li class="device-card" v-for="(v, k) in deviceInfo.list" :key="k"> <li class="device-card">
<!-- <div <DeviceStatus :deviceStatus="deviceInfo" />
class="device-card-head text-[16px] flex items-center mb-[12px]"
>
<img :src="v.icon" alt="" class="w-[32px]" />
<span class="ml-[12px]">{{ v.name }}</span>
<span class="font-bold">{{ v.bindVal?.total || 0 }}</span>
</div> -->
<!-- //TODO 使echarts https://echarts.zhangmuchen.top/#/detail?cid=164bb-40c1-e483-b7c9b-6cb171ad -->
<!-- // TODO -->
<DeviceStatus :deviceStatus="v.bindVal" />
</li> </li>
</ul> </ul>
</div> </div>
@ -457,7 +686,7 @@ onMounted(() => {
</div> </div>
<TrainAlarmInfoModel <TrainAlarmInfoModel
v-model:value="isTrainOpen" v-model:value="isTrainOpen"
:info="currentRow" :info="currentTrainRow"
@close="isTrainOpen = false" @close="isTrainOpen = false"
/> />
<AlarmModal <AlarmModal

@ -467,7 +467,9 @@ onUnmounted(() => {
<!-- 自定义标题栏 --> <!-- 自定义标题栏 -->
<template #header="{ close, titleId, titleClass }"> <template #header="{ close, titleId, titleClass }">
<div class="flex items-center justify-between"> <div class="flex items-center justify-between">
<div class="flex items-center justify-center w-full header-left mt-[32px]"> <div
class="flex items-center justify-center w-full header-left mt-[32px]"
>
<p <p
class="overflow-hidden whitespace-nowrap text-ellipsis max-w-[160px] fg-f-1 text-[24px]" class="overflow-hidden whitespace-nowrap text-ellipsis max-w-[160px] fg-f-1 text-[24px]"
> >
@ -486,9 +488,19 @@ onUnmounted(() => {
:disabled="!pcdLoaded" :disabled="!pcdLoaded"
@click="returnToCenter" @click="returnToCenter"
></span> ></span>
<span
class="button-fourth"
:class="{ 'active_view': !topView }"
:disabled="!pcdLoaded"
@click="toggleTopView"
>
</span>
<!-- 新增进度条 --> <!-- 新增进度条 -->
<div v-if="loading" class="pointModal-progress-bar"> <div v-if="loading" class="pointModal-progress-bar">
<div class="pointModal-progress" :style="{ width: progress + '%' }"></div> <div
class="pointModal-progress"
:style="{ width: progress + '%' }"
></div>
</div> </div>
</div> </div>
</el-dialog> </el-dialog>
@ -518,7 +530,8 @@ onUnmounted(() => {
.button-first, .button-first,
.button-second, .button-second,
.button-thrid { .button-thrid,
.button-fourth {
position: absolute; position: absolute;
width: 24px; width: 24px;
height: 24px; height: 24px;
@ -526,7 +539,7 @@ onUnmounted(() => {
background-size: 100% 100%; background-size: 100% 100%;
background-position: center; background-position: center;
background-repeat: no-repeat; background-repeat: no-repeat;
bottom: 112px; bottom: 122px;
right: 32px; right: 32px;
transition: all 0.3s ease; transition: all 0.3s ease;
} }
@ -536,16 +549,24 @@ onUnmounted(() => {
} }
.button-second { .button-second {
bottom: 72px; bottom: 82px;
right: 32px; right: 32px;
background-image: url("@/assets/common/reduce_btn.png"); background-image: url("@/assets/common/reduce_btn.png");
} }
.button-thrid { .button-thrid {
bottom: 33px; bottom: 42px;
right: 32px; right: 32px;
background-image: url("@/assets/common/reset_btn.png"); background-image: url("@/assets/common/reset_btn.png");
} }
.button-fourth {
bottom: 2px;
right: 32px;
background-image: url("@/assets/common/normal_view_btn.png");
&.active_view {
background-image: url("@/assets/common/top_view_btn.png");
}
}
.pointModal-progress-bar { .pointModal-progress-bar {
position: absolute; position: absolute;

@ -2,7 +2,7 @@
* @Author: donghao donghao@supervision.ltd * @Author: donghao donghao@supervision.ltd
* @Date: 2025-06-23 15:50:30 * @Date: 2025-06-23 15:50:30
* @LastEditors: donghao donghao@supervision.ltd * @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2025-09-05 16:48:36 * @LastEditTime: 2025-09-08 16:47:07
* @FilePath: \5G-Web\src\views\dashboard\components\TrainInfoModel.vue * @FilePath: \5G-Web\src\views\dashboard\components\TrainInfoModel.vue
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
--> -->
@ -13,7 +13,6 @@ interface Props {
/** 弹窗显隐 */ /** 弹窗显隐 */
value: boolean; value: boolean;
info: Record<string, any>; info: Record<string, any>;
image: any;
} }
interface Emits { interface Emits {
(e: "update:value", val: boolean): void; (e: "update:value", val: boolean): void;
@ -21,12 +20,9 @@ interface Emits {
const props = withDefaults(defineProps<Props>(), { const props = withDefaults(defineProps<Props>(), {
value: false, value: false,
info: {}, info: {},
image: []
}); });
const emit = defineEmits<Emits>(); const emit = defineEmits<Emits>();
const show = computed({ const show = computed({
get() { get() {
return props.value; return props.value;
@ -73,7 +69,7 @@ const itemCount = 16; // 这里可以根据实际需求动态设置
<div class="train_head_icon"></div> <div class="train_head_icon"></div>
</div> </div>
<ul :class="['train-card-item-list', { 'high-height': info?.data?.train_data?.length > 15 }]"> <ul :class="['train-card-item-list', { 'high-height': info?.data?.train_data?.length > 15 }]">
<li class="flex flex-1 train-card-item" v-for="(item, index) in info?.data?.train_data" :key="index"> <li class="flex flex-1 cursor-pointer train-card-item train-card-item-alarm" :class="{ ' train-card-item-default cursor-not-allowed': index === 0 }" v-for="(item, index) in info?.data?.train_data" :key="index">
<div class="w-[80px] px-[8px] flex flex-col justify-center"> <div class="w-[80px] px-[8px] flex flex-col justify-center">
<div>{{ item.model }}</div> <div>{{ item.model }}</div>
<div> <div>
@ -81,6 +77,9 @@ const itemCount = 16; // 这里可以根据实际需求动态设置
<span>{{ item.carriage_number }}</span> <span>{{ item.carriage_number }}</span>
</div> </div>
</div> </div>
<div class="default-tag" v-if="index===0">
无异常
</div>
</li> </li>
</ul> </ul>
</div> </div>
@ -93,5 +92,4 @@ const itemCount = 16; // 这里可以根据实际需求动态设置
<style lang="scss" > <style lang="scss" >
@import url('./TrainInfoModel.scss'); @import url('./TrainInfoModel.scss');
</style> </style>

@ -1,120 +1,141 @@
.trainModal-wrap.el-dialog { .trainModal-wrap.el-dialog {
.train-dialog-header { .train-dialog-header {
color: white; color: white;
padding: 0; padding: 0;
// padding-top: 8px; // padding-top: 8px;
// margin-bottom: 20px; // margin-bottom: 20px;
.header-left { .header-left {
padding: 0 24px; padding: 0 24px;
font-weight: bold; font-weight: bold;
font-size: 18px; font-size: 18px;
.header-icon { .header-icon {
width: 24px; width: 24px;
height: 48px; height: 48px;
background-image: url("@/assets/common/sub_title_icon.png"); background-image: url("@/assets/common/sub_title_icon.png");
background-size: contain; background-size: contain;
background-position: center; background-position: center;
background-repeat: no-repeat; background-repeat: no-repeat;
} }
}
} }
}
.train-content { .train-content {
box-sizing: border-box; box-sizing: border-box;
padding: 0 24px; padding: 0 24px;
width: 100%; width: 100%;
height: 100%; height: 100%;
.train-content-top { .train-content-top {
box-sizing: border-box; box-sizing: border-box;
width: 100%; width: 100%;
.train-content-top-img { .train-content-top-img {
box-sizing: border-box; box-sizing: border-box;
padding-top: 16px; padding-top: 16px;
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
justify-content: space-between; /* 水平方向均匀分布间距 */ justify-content: space-between; /* 水平方向均匀分布间距 */
align-content: space-between; /* 垂直方向均匀分布间距 */ align-content: space-between; /* 垂直方向均匀分布间距 */
}
img {
width: 568px;
height: 349px;
}
}
.train-content-bottom {
box-sizing: border-box;
margin-top: 12px;
} .train-content-bottom-train {
img { box-sizing: border-box;
width: 568px; padding-top: 16px;
height: 349px; display: flex;
} width: 100%;
height: 82px;
.train-card-item {
width: 80px;
height: 56px;
background-image: url("@/assets/trainManage/train_card_bg.png");
background-size: 100% 100%;
background-position: center;
background-repeat: no-repeat;
font-weight: 500;
font-size: 12px;
color: #37dbff;
border-radius: 2px;
.train_head_icon {
width: 48px;
height: 48px;
background-image: url("@/assets/trainManage/train_head.png");
background-size: 100% 100%;
background-position: center;
background-repeat: no-repeat;
}
} }
.train-content-bottom {
box-sizing: border-box;
margin-top: 12px;
.train-content-bottom-train { .train-card-item-alarm {
box-sizing: border-box; background: rgba(245,63,63,0.3);
padding-top: 16px; color: #f53f3f;
display: flex; border: 1px solid #f53f3f;
width: 100%;
height: 82px;
.train-card-item {
width: 80px;
height: 56px;
background-image: url("@/assets/trainManage/train_card_bg.png");
background-size: 100% 100%;
background-position: center;
background-repeat: no-repeat;
font-weight: 500;
font-size: 12px;
color: #37DBFF;
.train_head_icon{
width: 48px;
height: 48px;
background-image: url("@/assets/trainManage/train_head.png");
background-size: 100% 100%;
background-position: center;
background-repeat: no-repeat;
}
}
.train-card-item-list,
.high-height {
box-sizing: border-box;
width: 100%;
height: 82px;
padding: 16px 0;
display: flex;
// align-items: flex-end;
overflow-x: auto; /* 开启横向滚动 */
white-space: nowrap; /* 防止车厢内容换行 */
// background-color: #003366; /* 设置与背景相近颜色,这里假设深蓝色背景 */
padding: 0; /* 去除默认内边距 */
margin: 0; /* 去除默认外边距 */
margin-top: 18px;
gap: 8px; /* 车厢之间的间距 */
/* 自定义滚动条样式 */
&::-webkit-scrollbar {
height: 8px; /* 滚动条高度 */
background-color: transparent;
cursor: pointer;
}
&::-webkit-scrollbar-thumb {
background-color: rgba(255,255,255,0.6); /* 滚动条滑块颜色 */
border-radius: 4px; /* 滑块圆角 */
cursor: pointer;
}
}
}
} }
.train-content-bottom-title { .train-card-item-default {
width: 100%; position: relative;
box-sizing: border-box; color: #cacbce;
padding-left: 8px; background: rgba(202, 203, 206, 0.3);
height: 22px; border: 1px solid #cacbce;
font-weight: bold; .default-tag {
font-size: 14px; position: absolute;
color: #FFFFFF; top: 0;
border-left: 3px solid #46A9ED; right: 0;
line-height: 22px; width: 28px;
height: 16px;
line-height: 16px;
text-align: center;
background-color: #098137;
font-size: 8px;
font-weight: 700;
border-radius: 0px 1px 0px 2px;
}
}
.train-card-item-list,
.high-height {
box-sizing: border-box;
width: 100%;
height: 82px;
padding: 16px 0;
display: flex;
// align-items: flex-end;
overflow-x: auto; /* 开启横向滚动 */
white-space: nowrap; /* 防止车厢内容换行 */
// background-color: #003366; /* 设置与背景相近颜色,这里假设深蓝色背景 */
padding: 0; /* 去除默认内边距 */
margin: 0; /* 去除默认外边距 */
margin-top: 18px;
gap: 8px; /* 车厢之间的间距 */
/* 自定义滚动条样式 */
&::-webkit-scrollbar {
height: 8px; /* 滚动条高度 */
background-color: transparent;
cursor: pointer;
}
&::-webkit-scrollbar-thumb {
background-color: rgba(255, 255, 255, 0.6); /* 滚动条滑块颜色 */
border-radius: 4px; /* 滑块圆角 */
cursor: pointer;
}
} }
}
} }
.train-content-bottom-title {
width: 100%;
box-sizing: border-box;
padding-left: 8px;
height: 22px;
font-weight: bold;
font-size: 14px;
color: #ffffff;
border-left: 3px solid #46a9ed;
line-height: 22px;
}
}
} }
Loading…
Cancel
Save