设备看板

This commit is contained in:
xhf 2025-02-11 17:03:11 +08:00
parent 5736a5a82d
commit d64e339249
6 changed files with 412 additions and 527 deletions

View File

@ -4,7 +4,7 @@ NODE_ENV=development
VITE_DEV=true
# 请求路径
VITE_BASE_URL='http://192.168.0.66:48080'
VITE_BASE_URL='http://192.168.0.74:48080'
# VITE_BASE_URL='http://192.168.0.189:48080'
# 文件上传类型server - 后端上传, client - 前端直连上传,仅支持 S3 服务

56
src/api/device/index.ts Normal file
View File

@ -0,0 +1,56 @@
import request from '@/config/axios'
//agv 下载
export const agvDownload = async (params) => {
return await request.download({ url: `/system/position-map/agvDownload`, params })
}
//点位地图列表
export const getPositionMapList = async (params) => {
return await request.get({ url: `/system/position-map/list`, params })
}
//删除车辆信息
export const deleteRobotInformation = async (id: number) => {
return await request.delete({ url: `/system/robot/information/delete?id=` + id })
}
//查询所有车辆
export const getAllRobot = async (data) => {
return await request.post({ url: `/system/robot/information/getAllRobot`, data })
}
//获得车辆信息 详情
export const getRobotInformation = async (params) => {
return await request.get({ url: `/system/robot/information/get`, params })
}
//分页查询设备列表 看板信息设备目前用的是这个
export const deviceInformationPage = async (params) => {
return await request.get({ url: `/system/device/information/page`, params })
}
//统计车辆待命-任务中-离线
export const robotInformationStatistics = async (data) => {
return await request.post({ url: `/system/robot/information/statistics`, data })
}
// 创建车辆信息
export const robotInformationCreate = async (data) => {
return await request.post({ url: `/system/robot/information/create`, data })
}
// 编辑车辆信息
export const robotInformationUpdate = async (data) => {
return await request.put({ url: `/system/robot/information/update`, data })
}
//分页查询车辆列表 看板信息车辆目前用的是这个
export const robotGetAllModel = async (params) => {
return await request.get({ url: `/system/robot/model/getAllModel`, params })
}
// 范围选择
export const robotPositionGetMap = async (params) => {
return await request.get({ url: `/system/position-map/getMap`, params })
}
// 完整范围选择
export const robotPositionGetMapAll = async (params) => {
return await request.get({ url: `/system/position-map/getAllMap`, params })
}

View File

@ -2,7 +2,7 @@
<Dialog v-model="dialogVisible" :title="title" width="545px" class="task-dialog">
<el-form :model="formData" label-width="auto" ref="formRef" :rules="formRules">
<el-form-item label="车辆类型" prop="robotModelId" required>
<el-select v-model="formData.robotModelId" placeholder="请选择车辆类型" required>
<el-select v-model="formData.robotModelId" placeholder="请选择车辆类型" required :disabled="formData.id">
<el-option
:label="item.robotModelNumber"
:value="item.id"
@ -27,10 +27,11 @@
</el-select>
</el-form-item>
<el-form-item required label="自动充电电量" prop="autoCharge">
<el-input-number v-model="formData.autoCharge" :disabled="false" :controls="false" :precision="0" :step="1" type="number" :min="0" :max="99" placeholder="请输入自动充电电量">
<el-input-number style="width: 100px;" v-model="formData.autoCharge" :disabled="false" :controls="false" :precision="0" :step="1" type="number" :min="0" :max="99" placeholder="请输入自动充电电量">
<template #append>%</template>
</el-input-number>
<span style="margin-left: 20px;">%</span>
<span style="margin-left: 5px;">%</span>
<span style="margin-left: 4px;color: #C60606;font-size: 12px;">建议自动充电电量大于30%</span>
</el-form-item>
<el-form-item required label="Mac地址" prop="macAddress">
<el-input v-model="formData.macAddress" :disabled="false" placeholder="请输入Mac地址"/>

View File

@ -1,225 +1,4 @@
<template>
<div class="" v-if="false">
<ContentWrap>
<div class="top-box">
<el-button type="primary" @click="openForm('create')">新增车辆</el-button>
<el-input
v-model="queryParams.robotNo"
style="width: 240px"
placeholder="请输入关键字"
clearable
>
<template #append>
<el-button><Icon icon="ep:search" @click="getCarList" /></el-button
></template>
</el-input>
</div>
</ContentWrap>
<ContentWrap v-loading="formLoading">
<div style="width: 100%">
<div class="swiper-container" v-if="list.length >= 4">
<swiper
:modules="modules"
:loop="true"
:slides-per-view="list.length > 4 ? 4 : list.length"
:space-between="spaceBetween"
:navigation="navigation"
:pagination="{ clickable: true }"
:scrollbar="{ draggable: true }"
:direction="'horizontal'"
:observer="true"
:observeParents="true"
class="swiperBox"
>
<swiper-slide v-for="item in list" :key="item">
<div class="swiper-item-box">
<div class="swiper-item-box-top">
<el-button type="primary" size="small" @click="goToMap(item)">地图定位</el-button>
<div class="swiper-item-box-top-name"> {{ item.robotNo || '' }} </div>
<div class="swiper-item-box-top-msg">
<el-dropdown>
<div style="flex-shrink: 0">
<el-icon size="20px"><MoreFilled /></el-icon>
</div>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="openForm('update', item.id)"
>编辑</el-dropdown-item
>
<el-dropdown-item @click="clockCar(item)">{{
item.status == 0 ? '解锁' : '锁定'
}}</el-dropdown-item>
<el-dropdown-item @click="deleteCar(item.id)">删除</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</div>
<div class="swiper-item-img-box">
<img :src="item.url" alt="" class="swiper-item-img" />
</div>
<div class="swiper-item-box-msg">
<div class="swiper-item-box-msg-item">
<div class="swiper-item-box-msg-item-left"> 电量 </div>
<div class="swiper-item-box-msg-item-right" v-if="item.electricity">
{{ item.electricity || '' }} %</div
>
<div class="swiper-item-box-msg-item-right" v-else> 无电量数据</div>
</div>
<div class="swiper-item-box-msg-item">
<div class="swiper-item-box-msg-item-left"> 状态 </div>
<div class="swiper-item-box-msg-item-right">
{{
item.status == 0
? '暂停且无任务'
: item.status == 1
? '暂停(有处理中的任务)'
: item.status == 2
? '任务中'
: '待命'
}}
</div>
</div>
<div class="swiper-item-box-msg-item">
<div class="swiper-item-box-msg-item-left"> 楼层 </div>
<div class="swiper-item-box-msg-item-right"> 1 </div>
</div>
<div class="swiper-item-box-msg-item">
<div class="swiper-item-box-msg-item-left"> 区域 </div>
<div class="swiper-item-box-msg-item-right"> A </div>
</div>
<div class="swiper-item-box-msg-item">
<div class="swiper-item-box-msg-item-left"> 信息 </div>
<div class="swiper-item-box-msg-item-right"> 车辆正在待命 </div>
</div>
<el-button type="primary" size="small" style="margin-top: 30px"
>日志查看</el-button
>
</div>
</div>
</swiper-slide>
<div class="swiper-scrollbar"></div>
</swiper>
<div class="swiper-button-prev-custome" @click.stop="prevEl(item, index)">
<el-icon size="40px"><CaretLeft /></el-icon>
</div>
<div class="swiper-button-next-custome" @click.stop="nextEl">
<el-icon size="40px"><CaretRight /></el-icon
></div>
</div>
<!-- 不足四个数据的时候 -->
<div v-else class="letter-data-box">
<div
class="letter-data-item"
v-for="(item, index) in list"
:key="index"
:style="{ marginRight: index % 4 == 3 ? '0' : '20px' }"
>
<div class="swiper-item-box">
<div class="swiper-item-box-top">
<el-button type="primary" size="small" @click="goToMap(item)">地图定位</el-button>
<div class="swiper-item-box-top-name"> {{ item.robotNo || '' }} </div>
<div class="swiper-item-box-top-msg">
<el-dropdown>
<div style="flex-shrink: 0">
<el-icon size="20px"><MoreFilled /></el-icon>
</div>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="openForm('update', item.id)"
>编辑</el-dropdown-item
>
<el-dropdown-item @click="clockCar(item)">{{
item.status == 0 ? '解锁' : '锁定'
}}</el-dropdown-item>
<el-dropdown-item @click="deleteCar(item.id)">删除</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</div>
<div class="swiper-item-img-box">
<img :src="item.url" alt="" class="swiper-item-img" />
</div>
<div class="swiper-item-box-msg">
<div class="swiper-item-box-msg-item">
<div class="swiper-item-box-msg-item-left"> 电量 </div>
<div class="swiper-item-box-msg-item-right" v-if="item.electricity">
{{ item.electricity || '' }} %</div
>
<div class="swiper-item-box-msg-item-right" v-else> 无电量数据</div>
</div>
<div class="swiper-item-box-msg-item">
<div class="swiper-item-box-msg-item-left"> 状态 </div>
<!-- 0暂停且无任务1暂停(有处理中的任务)2任务中3待命 -->
<div class="swiper-item-box-msg-item-right">
{{
item.status == 0
? '暂停且无任务'
: item.status == 1
? '暂停(有处理中的任务)'
: item.status == 2
? '任务中'
: '待命'
}}
</div>
</div>
<div class="swiper-item-box-msg-item">
<div class="swiper-item-box-msg-item-left"> 楼层 </div>
<div class="swiper-item-box-msg-item-right"> {{ item.floor || '未知' }} </div>
</div>
<div class="swiper-item-box-msg-item">
<div class="swiper-item-box-msg-item-left"> 区域 </div>
<div class="swiper-item-box-msg-item-right"> {{ item.area || '未知' }} </div>
</div>
<div class="swiper-item-box-msg-item">
<div class="swiper-item-box-msg-item-left"> 信息 </div>
<div class="swiper-item-box-msg-item-right"> {{ item.msg || '' }} </div>
</div>
<el-button type="primary" size="small" style="margin-top: 30px">日志查看</el-button>
</div>
</div>
</div>
</div>
<!-- 车辆统计 -->
<div class="car-statistics-box" v-if="carStatistics">
<!-- carStatistics -->
<div class="car-statistics-item" style="color: #67c23a; border: 2px solid #67c23a">
<div class="car-statistics-item-name"> 待命中 </div>
<div class="car-statistics-item-value">
{{ carStatistics.standby || 0 }}
</div>
</div>
<div class="car-statistics-item" style="color: #e6a23c; border: 2px solid #e6a23c">
<div class="car-statistics-item-name"> 任务中 </div>
<div class="car-statistics-item-value">
{{ carStatistics.inTask || 0 }}
</div>
</div>
<div class="car-statistics-item" style="color: #409eff; border: 2px solid #409eff">
<div class="car-statistics-item-name"> 充电中 </div>
<div class="car-statistics-item-value">
{{ carStatistics.charge || 0 }}
</div>
</div>
<div class="car-statistics-item" style="color: #f56c6c; border: 2px solid #f56c6c">
<div class="car-statistics-item-name"> 离线 </div>
<div class="car-statistics-item-value">
{{ carStatistics.offline || 0 }}
</div>
</div>
</div>
</div>
</ContentWrap>
<createEditDialog ref="createEditDialogRef" @success="getCarList" />
</div>
<ContentWrap>
<div>
@ -229,7 +8,7 @@
<div class="new-top-box-left-statistics"> 总数 {{ carStatistics.total || 0 }} </div>
<div class="grey-line"> </div>
<!-- <el-divider direction="vertical" /> -->
<div style="display: flex; align-items: center" v-if="carStatistics">
<div style="display: flex; align-items: center" v-if="carStatistics" >
<div class="new-top-box-left-item" style="color: #00329f">
<div class="new-top-box-left-item-name">工作</div>
<div class="new-top-box-left-item-value">{{ carStatistics.inTask || 0 }}</div>
@ -700,6 +479,7 @@ onBeforeRouteLeave((to, from, next) => {
font-weight: 600;
font-size: 16px;
margin-left: 10px;
padding: 5px 0;
}
.new-top-box-left-item-name {
flex-shrink: 0;

View File

@ -1,264 +1,58 @@
<template>
<div class="" v-if="false">
<ContentWrap>
<div class="top-box">
<el-button type="primary" @click="openForm('create')">新增车辆</el-button>
<el-input
v-model="queryParams.robotNo"
style="width: 240px"
placeholder="请输入关键字"
clearable
>
<template #append>
<el-button><Icon icon="ep:search" @click="getCarList" /></el-button
></template>
</el-input>
</div>
</ContentWrap>
<ContentWrap v-loading="formLoading">
<div style="width: 100%">
<div class="swiper-container" v-if="list.length >= 4">
<swiper
:modules="modules"
:loop="true"
:slides-per-view="list.length > 4 ? 4 : list.length"
:space-between="spaceBetween"
:navigation="navigation"
:pagination="{ clickable: true }"
:scrollbar="{ draggable: true }"
:direction="'horizontal'"
:observer="true"
:observeParents="true"
class="swiperBox"
>
<swiper-slide v-for="item in list" :key="item">
<div class="swiper-item-box">
<div class="swiper-item-box-top">
<el-button type="primary" size="small" @click="goToMap(item)">地图定位</el-button>
<div class="swiper-item-box-top-name"> {{ item.robotNo || '' }} </div>
<div class="swiper-item-box-top-msg">
<el-dropdown>
<div style="flex-shrink: 0">
<el-icon size="20px"><MoreFilled /></el-icon>
</div>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="openForm('update', item.id)"
>编辑</el-dropdown-item
>
<el-dropdown-item @click="clockCar(item)">{{
item.status == 0 ? '解锁' : '锁定'
}}</el-dropdown-item>
<el-dropdown-item @click="deleteCar(item.id)">删除</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</div>
<div class="swiper-item-img-box">
<img :src="item.url" alt="" class="swiper-item-img" />
</div>
<div class="swiper-item-box-msg">
<div class="swiper-item-box-msg-item">
<div class="swiper-item-box-msg-item-left"> 电量 </div>
<div class="swiper-item-box-msg-item-right" v-if="item.electricity">
{{ item.electricity || '' }} %</div
>
<div class="swiper-item-box-msg-item-right" v-else> 无电量数据</div>
</div>
<div class="swiper-item-box-msg-item">
<div class="swiper-item-box-msg-item-left"> 状态 </div>
<div class="swiper-item-box-msg-item-right">
{{
item.status == 0
? '暂停且无任务'
: item.status == 1
? '暂停(有处理中的任务)'
: item.status == 2
? '任务中'
: '待命'
}}
</div>
</div>
<div class="swiper-item-box-msg-item">
<div class="swiper-item-box-msg-item-left"> 楼层 </div>
<div class="swiper-item-box-msg-item-right"> 1 </div>
</div>
<div class="swiper-item-box-msg-item">
<div class="swiper-item-box-msg-item-left"> 区域 </div>
<div class="swiper-item-box-msg-item-right"> A </div>
</div>
<div class="swiper-item-box-msg-item">
<div class="swiper-item-box-msg-item-left"> 信息 </div>
<div class="swiper-item-box-msg-item-right"> 车辆正在待命 </div>
</div>
<el-button type="primary" size="small" style="margin-top: 30px"
>日志查看</el-button
>
</div>
</div>
</swiper-slide>
<div class="swiper-scrollbar"></div>
</swiper>
<div class="swiper-button-prev-custome" @click.stop="prevEl(item, index)">
<el-icon size="40px"><CaretLeft /></el-icon>
</div>
<div class="swiper-button-next-custome" @click.stop="nextEl">
<el-icon size="40px"><CaretRight /></el-icon
></div>
</div>
<!-- 不足四个数据的时候 -->
<div v-else class="letter-data-box">
<div
class="letter-data-item"
v-for="(item, index) in list"
:key="index"
:style="{ marginRight: index % 4 == 3 ? '0' : '20px' }"
>
<div class="swiper-item-box">
<div class="swiper-item-box-top">
<el-button type="primary" size="small" @click="goToMap(item)">地图定位</el-button>
<div class="swiper-item-box-top-name"> {{ item.robotNo || '' }} </div>
<div class="swiper-item-box-top-msg">
<el-dropdown>
<div style="flex-shrink: 0">
<el-icon size="20px"><MoreFilled /></el-icon>
</div>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="openForm('update', item.id)"
>编辑</el-dropdown-item
>
<el-dropdown-item @click="clockCar(item)">{{
item.status == 0 ? '解锁' : '锁定'
}}</el-dropdown-item>
<el-dropdown-item @click="deleteCar(item.id)">删除</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</div>
<div class="swiper-item-img-box">
<img :src="item.url" alt="" class="swiper-item-img" />
</div>
<div class="swiper-item-box-msg">
<div class="swiper-item-box-msg-item">
<div class="swiper-item-box-msg-item-left"> 电量 </div>
<div class="swiper-item-box-msg-item-right" v-if="item.electricity">
{{ item.electricity || '' }} %</div
>
<div class="swiper-item-box-msg-item-right" v-else> 无电量数据</div>
</div>
<div class="swiper-item-box-msg-item">
<div class="swiper-item-box-msg-item-left"> 状态 </div>
<!-- 0暂停且无任务1暂停(有处理中的任务)2任务中3待命 -->
<div class="swiper-item-box-msg-item-right">
{{
item.status == 0
? '暂停且无任务'
: item.status == 1
? '暂停(有处理中的任务)'
: item.status == 2
? '任务中'
: '待命'
}}
</div>
</div>
<div class="swiper-item-box-msg-item">
<div class="swiper-item-box-msg-item-left"> 楼层 </div>
<div class="swiper-item-box-msg-item-right"> {{ item.floor || '未知' }} </div>
</div>
<div class="swiper-item-box-msg-item">
<div class="swiper-item-box-msg-item-left"> 区域 </div>
<div class="swiper-item-box-msg-item-right"> {{ item.area || '未知' }} </div>
</div>
<div class="swiper-item-box-msg-item">
<div class="swiper-item-box-msg-item-left"> 信息 </div>
<div class="swiper-item-box-msg-item-right"> {{ item.msg || '' }} </div>
</div>
<el-button type="primary" size="small" style="margin-top: 30px">日志查看</el-button>
</div>
</div>
</div>
</div>
<!-- 车辆统计 -->
<div class="car-statistics-box" v-if="carStatistics">
<!-- carStatistics -->
<div class="car-statistics-item" style="color: #67c23a; border: 2px solid #67c23a">
<div class="car-statistics-item-name"> 待命中 </div>
<div class="car-statistics-item-value">
{{ carStatistics.standby || 0 }}
</div>
</div>
<div class="car-statistics-item" style="color: #e6a23c; border: 2px solid #e6a23c">
<div class="car-statistics-item-name"> 任务中 </div>
<div class="car-statistics-item-value">
{{ carStatistics.inTask || 0 }}
</div>
</div>
<div class="car-statistics-item" style="color: #409eff; border: 2px solid #409eff">
<div class="car-statistics-item-name"> 充电中 </div>
<div class="car-statistics-item-value">
{{ carStatistics.charge || 0 }}
</div>
</div>
<div class="car-statistics-item" style="color: #f56c6c; border: 2px solid #f56c6c">
<div class="car-statistics-item-name"> 离线 </div>
<div class="car-statistics-item-value">
{{ carStatistics.offline || 0 }}
</div>
</div>
</div>
</div>
</ContentWrap>
<createEditDialog ref="createEditDialogRef" @success="getCarList" />
</div>
<ContentWrap>
<div>
<div class="new-top-box">
<div class="new-top-box-left">
<div class="new-top-box-left-title"> 车辆看板 </div>
<div class="new-top-box-left-title"> 设备看板 </div>
<!-- <el-divider direction="vertical" /> -->
<div class="new-top-box-left-statistics-box">
<div class="new-top-box-left-statistics-box-inner" v-if="carStatistics">
<div class="new-top-box-left-statistics"> 总数 {{ carStatistics.total || 0 }} </div>
<div class="grey-line"> </div>
<!-- <el-divider direction="vertical" /> -->
<div style="display: flex; align-items: center" v-if="carStatistics">
<div class="new-top-box-left-item" style="color: #00329f">
<div class="new-top-box-left-item-name">工作</div>
<div class="new-top-box-left-item">
<div class="new-top-box-left-item-name">充电桩</div>
<div class="new-top-box-left-item-value">{{ carStatistics.inTask || 0 }}</div>
<div class="grey-line" style="margin-left: 8px"> </div>
</div>
<div class="new-top-box-left-item" style="color: #e07300">
<div class="new-top-box-left-item-name">充电</div>
<div class="new-top-box-left-item">
<div class="new-top-box-left-item-name">输送线</div>
<div class="new-top-box-left-item-value">{{ carStatistics.charge || 0 }}</div>
<div class="grey-line" style="margin-left: 8px"> </div>
</div>
<div class="new-top-box-left-item" style="color: #c60606">
<div class="new-top-box-left-item-name">异常</div>
<div class="new-top-box-left-item">
<div class="new-top-box-left-item-name">码垛机</div>
<div class="new-top-box-left-item-value">{{ carStatistics.fault || 0 }}</div>
<div class="grey-line" style="margin-left: 8px"> </div>
</div>
<div class="new-top-box-left-item" style="color: #f1cd0b">
<div class="new-top-box-left-item-name">锁定</div>
<div class="new-top-box-left-item-value">{{ carStatistics.doLock || 0 }}</div>
<div class="new-top-box-left-item">
<div class="new-top-box-left-item-name">自动门</div>
<div class="new-top-box-left-item-value">{{ carStatistics.fault || 0 }}</div>
<div class="grey-line" style="margin-left: 8px"> </div>
</div>
<div class="new-top-box-left-item" style="color: #4dc606">
<div class="new-top-box-left-item-name">待命</div>
<div class="new-top-box-left-item-value">{{ carStatistics.standby || 0 }}</div>
<div class="new-top-box-left-item">
<div class="new-top-box-left-item-name">提升机</div>
<div class="new-top-box-left-item-value">{{ carStatistics.fault || 0 }}</div>
<div class="grey-line" style="margin-left: 8px"> </div>
</div>
<div class="new-top-box-left-item" style="color: #7a7a7a">
<div class="new-top-box-left-item-name">离线</div>
<div class="new-top-box-left-item-value">{{ carStatistics.offline || 0 }}</div>
<div class="new-top-box-left-item">
<div class="new-top-box-left-item-name">信号灯</div>
<div class="new-top-box-left-item-value">{{ carStatistics.fault || 0 }}</div>
<div class="grey-line" style="margin-left: 8px"> </div>
</div>
<div class="new-top-box-left-item">
<div class="new-top-box-left-item-name">按钮盒</div>
<div class="new-top-box-left-item-value">{{ carStatistics.fault || 0 }}</div>
<div class="grey-line" style="margin-left: 8px"> </div>
</div>
<div class="new-top-box-left-item">
<div class="new-top-box-left-item-name">拆垛机</div>
<div class="new-top-box-left-item-value">{{ carStatistics.fault || 0 }}</div>
<div class="grey-line" style="margin-left: 8px"> </div>
</div>
</div>
</div>
</div>
<div class="new-top-box-right">
@ -290,7 +84,7 @@
class="new-top-box-right-input-icon"
/>
</div>
<div class="new-top-box-right-button" @click="openForm('create')"> 新增车辆 </div>
<div class="new-top-box-right-button" @click="openForm('create')"> 新增设备 </div>
</div>
</div>
</div>
@ -301,7 +95,7 @@
<div class="item-top">
<div class="item-inner-left-name">
<div class="item-inner-left-name-inner">
{{ item.robotNo }}
{{ formatterDeviceType(item.deviceType) }} {{ item.deviceNo }}
</div>
</div>
<div class="item-inner-right-top">
@ -325,7 +119,6 @@
</div>
<div class="item-inner">
<div class="item-inner-left">
<div class="item-inner-left-img-box">
<el-image style="width: 100%; height: 100%" :src="url" :fit="'fill'" />
</div>
@ -335,30 +128,28 @@
</div>
</div>
<div class="item-inner-right-msg">
<div class="item-inner-right-msg-item m-b-10">
<!-- <div class="item-inner-right-msg-item m-b-10">
<div class="item-inner-right-msg-item-name">电量</div>
<div class="item-inner-right-msg-item-value" :style="{color:item.electricity>20?'#4DC606':'#C60606'}" v-if="item.electricity">{{ item.electricity || '' }} %</div>
</div>
</div> -->
<div class="item-inner-right-msg-item m-b-10">
<div class="item-inner-right-msg-item-name">状态</div>
<div class="item-inner-right-msg-item-value" >
<span v-if="item.robotStatus == 0" style="color: #C60606;">待命</span>
<span v-if="item.robotStatus == 1" style="color: #F1CD0B;">暂停</span>
<span v-if="item.robotStatus == 2" style="color: #01D3D8;">工作中</span>
<span v-if="item.robotStatus == 3" style="color: #4DC606;">待命中</span>
<div class="item-inner-right-msg-item-name">是否启用</div>
<div class="item-inner-right-msg-item-value">
<span v-if="item.robotStatus == 0" style="color: #c60606">禁用</span>
<span v-if="item.robotStatus == 1" style="color: #4dc606">启用</span>
</div>
</div>
<div class="item-inner-right-msg-item m-b-10">
<div class="item-inner-right-msg-item-name">楼层</div>
<div class="item-inner-right-msg-item-value" v-if="item.floor!==null">{{ item.floor || '' }} </div>
<div class="item-inner-right-msg-item-name">位置</div>
<div class="item-inner-right-msg-item-value" v-if="item.deviceLocation !== null"
>{{ item.deviceLocation || '' }}
</div>
<div class="item-inner-right-msg-item m-b-10">
<div class="item-inner-right-msg-item-name">区域</div>
<div class="item-inner-right-msg-item-value" v-if="item.area!==null">{{ item.area || '' }} </div>
</div>
<div class="item-inner-right-msg-item m-b-10">
<div class="item-inner-right-msg-item-name">信息</div>
<div class="item-inner-right-msg-item-value" v-if="item.msg!==null">{{ item.msg || '' }} </div>
<div class="item-inner-right-msg-item">
<div class="item-inner-right-msg-item-name">最后通讯时间</div>
<div class="item-inner-right-msg-item-value" v-if="item.deviceLastTime !== null"
>{{ item.deviceLastTime || '' }}
</div>
</div>
</div>
</div>
@ -366,12 +157,13 @@
</div>
</div>
<createEditDialog ref="createEditDialogRef" @success="getCarList" />
</template>
<script setup>
import { ref, reactive, onMounted, onBeforeUnmount } from 'vue'
defineOptions({ name: 'BoardCarBoard' })
import * as CarApi from '@/api/car/index'
defineOptions({ name: 'BoardDevice' })
import * as DeviceApi from '@/api/device/index'
import { Swiper, SwiperSlide } from 'swiper/vue'
// API
import { onBeforeRouteLeave, onBeforeRouteUpdate } from 'vue-router'
@ -384,6 +176,8 @@ import 'swiper/css/navigation' // 轮播图两边的左右箭头
import { Autoplay, Pagination, Navigation, Scrollbar } from 'swiper'
import createEditDialog from './createEditDialog.vue'
import 'swiper/css'
import { formatter } from 'element-plus'
const router = useRouter() //
const createEditDialogRef = ref(null)
const list = ref([])
@ -411,6 +205,70 @@ const onSlideChange = (swiper) => {
// swiperswiperactiveIndex
console.log(swiper.activeIndex)
}
// (1:,2:线,3:,4:,5:,6:,7:,8:)
const formatterDeviceType = (deviceType) => {
switch (deviceType) {
case 1:
return '充电桩'
case 2:
return '输送线'
case 3:
return '码垛机'
case 4:
return '自动门'
case 5:
return '提升机'
case 6:
return '信号灯'
case 7:
return '按钮盒'
case 8:
return '拆垛机'
}
}
const topList = ref([
{
name: '总数',
count: 0,
id:-1
},
{
name: '充电桩',
count: 0,
id:1
},
{
name: '输送线',
count: 0,
id:2
},
{
name: '码垛机',
count: 0,
id:3
},
{
name: '自动门',
count: 0,
id:4
},
{
name: '提升机',
count: 0
},
{
name: '信号灯',
count: 0
},
{
name: '按钮盒',
count: 0
},
{
name: '拆垛机',
count: 0
}
])
const timerRef = ref(null)
//
const getCarList = async () => {
@ -422,7 +280,7 @@ const getCarList = async () => {
getCarList()
getRobotInformationStatistics()
}, 5000)
let res = await CarApi.robotInformationPage(queryParams)
let res = await DeviceApi.deviceInformationPage(queryParams)
// console.log(res.list)
list.value = res.list
}
@ -437,7 +295,7 @@ const carStatistics = ref({
})
//
const getRobotInformationStatistics = async () => {
let res = await CarApi.robotInformationStatistics({})
let res = await DeviceApi.robotInformationStatistics({})
console.log('车辆统计', res)
if (res) {
carStatistics.value = res
@ -472,7 +330,7 @@ const deleteCar = (id) => {
type: 'warning'
})
.then(() => {
CarApi.deleteRobotInformation(id).then((res) => {
DeviceApi.deleteRobotInformation(id).then((res) => {
getCarList()
message.success('删除成功')
})
@ -495,7 +353,7 @@ const clockCar = (item) => {
type: 'warning'
})
.then(() => {
CarApi.robotInformationUpdate(data).then((res) => {
DeviceApi.robotInformationUpdate(data).then((res) => {
getCarList()
message.success(`${valueStr}成功`)
})
@ -658,12 +516,14 @@ onBeforeRouteLeave((to, from, next) => {
/* padding: 25px 0; */
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
flex-wrap: nowrap;
}
.new-top-box-left {
flex-shrink: 0;
display: flex;
align-items: center;
flex: 1;
margin-right: 10px;
}
.new-top-box-left-title {
font-family:
@ -700,6 +560,8 @@ onBeforeRouteLeave((to, from, next) => {
font-weight: 600;
font-size: 16px;
margin-left: 10px;
padding: 5px 0;
cursor: pointer;
}
.new-top-box-left-item-name {
flex-shrink: 0;
@ -748,6 +610,20 @@ input::-webkit-input-placeholder {
color: #536387;
cursor: pointer;
}
.new-top-box-left-statistics-box{
flex: 1;
margin-left: 10px;
/* background: red; */
}
.new-top-box-left-statistics-box-inner{
display: flex;
align-items: center;
flex-shrink: 0;
flex: 1;
overflow: hidden;
margin: 0 10px;
}
.new-list-box {
margin-top: 20px;
display: grid;
@ -783,7 +659,7 @@ input::-webkit-input-placeholder {
font-size: 14px;
width: 0;
}
.item-inner-left-name-inner{
.item-inner-left-name-inner {
white-space: nowrap; /* 防止文本换行 */
overflow: hidden; /* 隐藏超出容器的部分 */
text-overflow: ellipsis; /* 显示省略号来表示被截断的文本 */
@ -816,7 +692,7 @@ input::-webkit-input-placeholder {
flex: 1;
height: 100%;
}
.item-top{
.item-top {
display: flex;
align-items: center;
justify-content: space-between;
@ -827,28 +703,29 @@ input::-webkit-input-placeholder {
display: flex;
justify-content: flex-end;
}
.item-inner-right-msg{
.item-inner-right-msg {
margin-left: 35px;
flex: 1;
}
.item-inner-right-msg-item{
.item-inner-right-msg-item {
width: 100%;
display: flex;
flex-shrink: 0;
}
.item-inner-right-msg-item-name{
font-family: PingFangSC, PingFang SC;
.item-inner-right-msg-item-name {
font-family:
PingFangSC,
PingFang SC;
font-weight: 400;
font-size: 14px;
}
.item-inner-right-msg-item-value{
.item-inner-right-msg-item-value {
flex: 1;
margin-left: 8px;
font-size: 14px;
color: #0D162A;
color: #0d162a;
}
.m-b-10{
.m-b-10 {
margin-bottom: 10px;
}
</style>

View File

@ -0,0 +1,171 @@
<template>
<div class="tabs-container">
<!-- 左箭头 -->
<div
v-if="showArrows && canScrollLeft"
class="arrow arrow-left"
@click="scrollLeft"
>left</div>
<!-- 滚动容器 -->
<div class="tabs-scroll" ref="scrollRef" @scroll="handleScroll">
<div class="tabs">
<div
v-for="(tab, index) in tabs"
:key="index"
:class="['tab-item', { active: activeTab === index }, tab.class]"
@click="setActiveTab(index)"
>
<slot :name="`tab-${index}`"></slot>
</div>
</div>
</div>
<!-- 右箭头 -->
<div
v-if="showArrows && canScrollRight"
class="arrow arrow-right"
@click="scrollRight"
>right</div>
<!-- 内容区域 -->
<div class="tabs-content">
<slot :name="`content-${activeTab}`"></slot>
</div>
</div>
</template>
<script setup>
import { ref, onMounted, watch } from 'vue';
// tab
const props = defineProps({
defaultActiveTab: {
type: Number,
default: 0
}
});
// tab
const activeTab = ref(props.defaultActiveTab);
//
const scrollRef = ref(null);
//
const canScrollLeft = ref(false);
//
const canScrollRight = ref(false);
//
const showArrows = ref(false);
// tab
const setActiveTab = (index) => {
activeTab.value = index;
};
// tab
const tabs = [];
const slots = useSlots();
for (const key in slots) {
if (key.startsWith('tab-')) {
const index = parseInt(key.split('-')[1]);
const classProp = slots[`class-${index}`]?.()[0]?.props?.innerHTML;
tabs[index] = { class: classProp };
}
}
//
const handleScroll = () => {
const scrollEl = scrollRef.value;
canScrollLeft.value = scrollEl.scrollLeft > 0;
canScrollRight.value = scrollEl.scrollLeft < scrollEl.scrollWidth - scrollEl.clientWidth;
};
//
const scrollLeft = () => {
const scrollEl = scrollRef.value;
scrollEl.scrollLeft -= 200;
};
//
const scrollRight = () => {
const scrollEl = scrollRef.value;
scrollEl.scrollLeft += 200;
};
const checkArrowsVisibility = () => {
const scrollEl = scrollRef.value;
showArrows.value = scrollEl.scrollWidth > scrollEl.clientWidth;
};
onMounted(() => {
checkArrowsVisibility();
handleScroll();
});
//
watch(
() => scrollRef.value?.scrollWidth,
() => {
checkArrowsVisibility();
handleScroll();
}
);
</script>
<style scoped>
.tabs-container {
position: relative;
width: 100%;
}
.arrow {
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 30px;
height: 30px;
background-color: rgba(0, 0, 0, 0.1);
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
z-index: 1;
}
.arrow-left {
left: 0;
}
.arrow-right {
right: 0;
}
.tabs-scroll {
width: 100%;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
scroll-behavior: smooth;
scrollbar-width: none;
-ms-overflow-style: none;
}
.tabs-scroll::-webkit-scrollbar {
display: none;
}
.tabs {
display: flex;
white-space: nowrap;
}
.tab-item {
padding: 10px 15px;
cursor: pointer;
}
.tab-item.active {
font-weight: bold;
}
.tabs-content {
padding: 15px;
border-top: 1px solid #eee;
}
</style>