Merge branch 'xhf' of http://git.znkjfw.com/ak/zn-admin-vue3-wcs into xhf
2
.env.dev
@ -6,7 +6,7 @@ VITE_DEV=true
|
||||
# 请求路径
|
||||
# VITE_BASE_URL='http://192.168.0.66:48080'
|
||||
# VITE_BASE_URL='http://192.168.0.189:48080'
|
||||
VITE_BASE_URL='http://192.168.0.74:48080'
|
||||
VITE_BASE_URL='http://192.168.0.66:48080'
|
||||
|
||||
# 文件上传类型:server - 后端上传, client - 前端直连上传,仅支持S3服务
|
||||
VITE_UPLOAD_TYPE=server
|
||||
|
BIN
src/assets/imgs/indexPage/chache-4@2x(1).png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
src/assets/imgs/indexPage/chache-4@2x.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
src/assets/imgs/indexPage/chache-4备份 2@2x.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
src/assets/imgs/indexPage/chache-4备份 3@2x.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
src/assets/imgs/indexPage/chache-4备份 4@2x.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
src/assets/imgs/indexPage/chache-4备份 5@2x.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
src/assets/imgs/indexPage/chache-4备份 6@2x.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
src/assets/imgs/indexPage/chache-4备份 7@2x.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
src/assets/imgs/indexPage/chache-4备份 8@2x.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
src/assets/imgs/indexPage/chache-4备份 9@2x.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
src/assets/imgs/indexPage/chache-4备份@2x.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
src/assets/imgs/indexPage/chongdianzhuang_ceshi@2x.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
src/assets/imgs/indexPage/shusongxian-youhuo@2x.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
src/assets/imgs/indexPage/shusongxian@2x.png
Normal file
After Width: | Height: | Size: 727 B |
BIN
src/assets/imgs/indexPage/tuopan备份 18@2x.png
Normal file
After Width: | Height: | Size: 767 B |
BIN
src/assets/imgs/indexPage/tuopan备份 62@2x.png
Normal file
After Width: | Height: | Size: 428 B |
BIN
src/assets/imgs/indexPage/直线 4备份@2x.png
Normal file
After Width: | Height: | Size: 101 B |
BIN
src/assets/imgs/indexPage/直线备份@2x.png
Normal file
After Width: | Height: | Size: 98 B |
BIN
src/assets/imgs/indexPage/编组 10@2x.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
src/assets/imgs/indexPage/编组 11@2x.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
src/assets/imgs/indexPage/编组 12@2x.png
Normal file
After Width: | Height: | Size: 860 B |
BIN
src/assets/imgs/indexPage/编组 13@2x.png
Normal file
After Width: | Height: | Size: 551 B |
BIN
src/assets/imgs/indexPage/编组 15@2x(1).png
Normal file
After Width: | Height: | Size: 8.6 KiB |
BIN
src/assets/imgs/indexPage/编组 15@2x.png
Normal file
After Width: | Height: | Size: 8.0 KiB |
BIN
src/assets/imgs/indexPage/编组 15备份 2@2x.png
Normal file
After Width: | Height: | Size: 8.8 KiB |
BIN
src/assets/imgs/indexPage/编组 15备份 3@2x.png
Normal file
After Width: | Height: | Size: 8.8 KiB |
BIN
src/assets/imgs/indexPage/编组 15备份 4@2x.png
Normal file
After Width: | Height: | Size: 8.7 KiB |
BIN
src/assets/imgs/indexPage/编组 15备份@2x.png
Normal file
After Width: | Height: | Size: 8.8 KiB |
BIN
src/assets/imgs/indexPage/编组 16@2x.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
src/assets/imgs/indexPage/编组 17@2x.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
src/assets/imgs/indexPage/编组 18@2x.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
src/assets/imgs/indexPage/编组 19@2x.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
src/assets/imgs/indexPage/编组 24@2x.png
Normal file
After Width: | Height: | Size: 443 B |
BIN
src/assets/imgs/indexPage/编组 2@2x.png
Normal file
After Width: | Height: | Size: 7.9 KiB |
BIN
src/assets/imgs/indexPage/编组 3@2x.png
Normal file
After Width: | Height: | Size: 7.7 KiB |
BIN
src/assets/imgs/indexPage/编组 4@2x.png
Normal file
After Width: | Height: | Size: 7.8 KiB |
BIN
src/assets/imgs/indexPage/编组 4备份 26@2x.png
Normal file
After Width: | Height: | Size: 732 B |
BIN
src/assets/imgs/indexPage/编组 4备份 27@2x.png
Normal file
After Width: | Height: | Size: 732 B |
BIN
src/assets/imgs/indexPage/编组 4备份 37@2x.png
Normal file
After Width: | Height: | Size: 751 B |
BIN
src/assets/imgs/indexPage/编组 4备份 38@2x.png
Normal file
After Width: | Height: | Size: 751 B |
BIN
src/assets/imgs/indexPage/编组 6@2x.png
Normal file
After Width: | Height: | Size: 7.8 KiB |
BIN
src/assets/imgs/indexPage/编组 7@2x.png
Normal file
After Width: | Height: | Size: 7.8 KiB |
BIN
src/assets/imgs/indexPage/编组 8@2x.png
Normal file
After Width: | Height: | Size: 481 B |
BIN
src/assets/imgs/indexPage/编组 9@2x.png
Normal file
After Width: | Height: | Size: 859 B |
BIN
src/assets/imgs/indexPage/编组@2x.png
Normal file
After Width: | Height: | Size: 7.7 KiB |
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<Dialog v-model="dialogVisible" :title="title" width="545px" class="task-dialog">
|
||||
<Dialog v-model="dialogVisible" :title="title" width="545px" style="padding: 0;">
|
||||
<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 :disabled="formData.id">
|
||||
@ -48,9 +48,11 @@
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
<el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||
<template #footer >
|
||||
<div style="padding: 0 10px 10px 0;">
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
<el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</Dialog>
|
||||
</template>
|
||||
@ -226,17 +228,14 @@ const resetForm = () => {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.task-dialog {
|
||||
|
||||
// .el-dialog__header {
|
||||
// border-bottom: none;
|
||||
// }
|
||||
|
||||
.el-dialog__footer {
|
||||
border-top: none !important;
|
||||
}
|
||||
<style lang="scss" scoped>
|
||||
::v-deep .el-dialog {
|
||||
padding: 0 !important;
|
||||
}
|
||||
::v-deep .el-dialog__header {
|
||||
border-bottom: 1px solid #e8e8e8 !important;
|
||||
}
|
||||
|
||||
|
||||
.task-tips {
|
||||
display: flex;
|
||||
|
@ -79,17 +79,6 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="new-top-box-right">
|
||||
<!-- <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>
|
||||
<el-button type="primary" @click="openForm('create')">新增车辆</el-button> -->
|
||||
<div class="new-top-box-right-input-box">
|
||||
<input
|
||||
type="text"
|
||||
@ -236,8 +225,8 @@
|
||||
<div class="item-inner-right-msg-item-name">车辆状态</div>
|
||||
<div class="item-inner-right-msg-item-value">
|
||||
<span v-if="item.robotEssenceStatus == 2" style="color: #c60606">异常</span>
|
||||
<span v-if="item.robotEssenceStatus == 1" style="color: #f1cd0b">锁定</span>
|
||||
<span v-if="item.robotEssenceStatus == 0" style="color: #4dc606">空闲</span>
|
||||
<span v-if="item.robotEssenceStatus == 0" style="color: #f1cd0b">锁定</span>
|
||||
<span v-if="item.robotEssenceStatus == 1" style="color: #4dc606">空闲</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item-inner-right-msg-item m-b-10">
|
||||
@ -321,6 +310,7 @@ const message = useMessage() // 消息弹窗
|
||||
// 引入swiper核心和所需模块
|
||||
// import { Autoplay, Pagination, Navigation, Scrollbar } from 'swiper'
|
||||
import createEditDialog from './createEditDialog.vue'
|
||||
const route = useRoute() // 路由
|
||||
// import 'swiper/css'
|
||||
const router = useRouter() // 路由对象
|
||||
const createEditDialogRef = ref(null)
|
||||
@ -472,6 +462,9 @@ const goToMap = (item) => {
|
||||
})
|
||||
}
|
||||
onMounted(() => {
|
||||
if(route.query.robotNo){
|
||||
queryParams.robotNo = route.query.robotNo
|
||||
}
|
||||
getCarList()
|
||||
getRobotInformationStatistics()
|
||||
})
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<Dialog v-model="dialogVisible" :title="title" width="545" class="task-dialog">
|
||||
<Dialog v-model="dialogVisible" :title="title" width="545" style="padding: 0;">
|
||||
<el-form :model="formData" label-width="auto" ref="formRef" :rules="formRules">
|
||||
<el-form-item label="设备类型" prop="robotModelId" >
|
||||
<el-select v-model="formData.deviceType" clearable placeholder="请选择设备类型">
|
||||
@ -34,8 +34,10 @@
|
||||
</el-form>
|
||||
|
||||
<template #footer>
|
||||
<el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||
<div style="padding: 0 10px 10px 0;">
|
||||
<el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</Dialog>
|
||||
</template>
|
||||
@ -174,15 +176,12 @@ const resetForm = () => {
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.task-dialog {
|
||||
.el-dialog__header {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.el-dialog__footer {
|
||||
border-top: none !important;
|
||||
}
|
||||
<style scoped>
|
||||
::v-deep .el-dialog {
|
||||
padding: 0 !important;
|
||||
}
|
||||
::v-deep .el-dialog__header {
|
||||
border-bottom: 1px solid #e8e8e8 !important;
|
||||
}
|
||||
|
||||
.task-tips {
|
||||
|
186
src/views/mapPage/realTimeMap/components/carDialog.vue
Normal file
@ -0,0 +1,186 @@
|
||||
<template>
|
||||
<Dialog v-model="dialogVisible" title="车辆信息" width="545" style="padding: 0">
|
||||
<div class="dialog-box">
|
||||
<div class="dialog-box-left" :style="{ background: formData.url?'#ffffff':'#EEEEEE' }">
|
||||
<el-image style="width: 100%; height: 100%" :src="formData.url" fit="contain" />
|
||||
</div>
|
||||
<div class="dialog-box-right">
|
||||
<div class="dialog-box-right-top">
|
||||
<div class="dialog-box-right-top-btn"> 急停 </div>
|
||||
</div>
|
||||
<div class="dialog-box-right-item">
|
||||
<div class="dialog-box-right-item-left"> 编号 </div>
|
||||
<div class="dialog-box-right-item-right">
|
||||
{{ formData.robotNo || '' }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="dialog-box-right-item">
|
||||
<div class="dialog-box-right-item-left"> 电量 </div>
|
||||
<div class="dialog-box-right-item-right">
|
||||
{{ formData.electricity || '' }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="dialog-box-right-item">
|
||||
<div class="dialog-box-right-item-left"> 车辆状态 </div>
|
||||
<div class="dialog-box-right-item-right">
|
||||
<span v-if="formData.robotEssenceStatus == 2" style="color: #c60606">异常</span>
|
||||
<span v-if="formData.robotEssenceStatus == 0" style="color: #f1cd0b">锁定</span>
|
||||
<span v-if="formData.robotEssenceStatus == 1" style="color: #4dc606">空闲</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dialog-box-right-item">
|
||||
<div class="dialog-box-right-item-left"> 任务状态 </div>
|
||||
<div class="dialog-box-right-item-right">
|
||||
<span v-if="formData.robotTaskStatus == 1" style="color: #f1cd0b">工作中</span>
|
||||
<span v-if="formData.robotTaskStatus == 0" style="color: #4dc606">待命中</span>
|
||||
<span v-if="formData.robotTaskStatus == 2" style="color: #e07300">充电中</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dialog-box-right-item">
|
||||
<div class="dialog-box-right-item-left"> 楼层 </div>
|
||||
<div class="dialog-box-right-item-right">
|
||||
{{ formData.floor || '' }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="dialog-box-right-item">
|
||||
<div class="dialog-box-right-item-left"> 区域 </div>
|
||||
<div class="dialog-box-right-item-right">
|
||||
{{ formData.area || '' }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="dialog-box-right-item">
|
||||
<div class="dialog-box-right-item-left"> 信息 </div>
|
||||
<div class="dialog-box-right-item-right">
|
||||
{{ formData.msg || '' }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="dialog-box-right-item">
|
||||
<div class="dialog-box-right-item-left" style="color: #1677FF;cursor: pointer;" @click="goCarBord"> 更多操作 </div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
const { t } = useI18n() // 国际化
|
||||
const message = useMessage() // 消息弹窗
|
||||
import * as CarApi from '@/api/car/index'
|
||||
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||
const id = ref('')
|
||||
const formData = ref({})
|
||||
const formRules = reactive({})
|
||||
const selectIndex = ref(0)
|
||||
const formRef = ref() // 表单 Ref
|
||||
const storeData = ref([])
|
||||
/** 打开弹窗 */
|
||||
const open = async (data) => {
|
||||
console.log(data)
|
||||
|
||||
resetForm()
|
||||
if (data.data.id) {
|
||||
let paramsData = await CarApi.getRobotInformation({ id: data.data.id })
|
||||
console.log(paramsData)
|
||||
formData.value = paramsData
|
||||
}
|
||||
dialogVisible.value = true
|
||||
}
|
||||
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||
|
||||
//前往任务管理页面
|
||||
const { push } = useRouter()
|
||||
|
||||
/** 重置表单 */
|
||||
const resetForm = () => {
|
||||
// formData.value = {
|
||||
// locationNo: undefined, //库位编号
|
||||
// areaName: undefined, //区域名称
|
||||
// locationUseStatus: undefined, //库位状态 (0:空闲、1:占用)
|
||||
// locationEnable: undefined, //是否禁用(0:禁用、1:启用)
|
||||
// skuInfo: undefined //物料信息
|
||||
// }
|
||||
// formRef.value?.resetFields()
|
||||
}
|
||||
const goCarBord = () => {
|
||||
push({
|
||||
path: '/board/carBoard',
|
||||
query: {
|
||||
robotNo: formData.value.robotNo
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
::v-deep .el-dialog {
|
||||
padding: 0 !important;
|
||||
}
|
||||
::v-deep .el-dialog__header {
|
||||
border-bottom: 1px solid #e8e8e8 !important;
|
||||
}
|
||||
|
||||
.el-dialog__footer {
|
||||
border-top: none !important;
|
||||
}
|
||||
.dialog-box {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
padding: 15px;
|
||||
padding-top: 0;
|
||||
}
|
||||
.dialog-box-left {
|
||||
width: 252px;
|
||||
height: 324px;
|
||||
background: #eeeeee;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.dialog-box-right {
|
||||
margin-left: 24px;
|
||||
flex: 1;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.dialog-box-right-top {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.dialog-box-right-top-btn {
|
||||
width: 104px;
|
||||
height: 36px;
|
||||
background: #c60606;
|
||||
font-family:
|
||||
PingFangSC,
|
||||
PingFang SC;
|
||||
font-weight: 400;
|
||||
font-size: 14px;
|
||||
color: #ffffff;
|
||||
text-align: center;
|
||||
line-height: 36px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.dialog-box-right-item {
|
||||
display: flex;
|
||||
margin-top: 24px;
|
||||
}
|
||||
.dialog-box-right-item-left {
|
||||
font-family:
|
||||
PingFangSC,
|
||||
PingFang SC;
|
||||
font-weight: 400;
|
||||
font-size: 14px;
|
||||
color: #0d162a;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.dialog-box-right-item-right {
|
||||
font-family:
|
||||
PingFangSC,
|
||||
PingFang SC;
|
||||
font-weight: 500;
|
||||
font-size: 18px;
|
||||
color: #0d162a;
|
||||
margin-left: 10px;
|
||||
flex: 1;
|
||||
flex-wrap: wrap;
|
||||
word-break:break-all;
|
||||
}
|
||||
</style>
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="affix-container" :style="{ height: heightVal + 'px' }">
|
||||
<el-affix target=".affix-container" :offset="80">
|
||||
<div class="affix-container" :style="{ height: (heightVal*radio ) + 'px'}">
|
||||
<!-- <el-affix target=".affix-container" :offset="80">
|
||||
<span @click="resetPosition ">回到原点</span>
|
||||
<div class="affix-container-top">
|
||||
<el-scrollbar>
|
||||
@ -28,13 +28,14 @@
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</el-affix>
|
||||
</el-affix> -->
|
||||
<div class="indexpage-container" v-if="imgUrl" v-drag="true" :style="{scale:1,transformOrigin:'0 0'}" ref="draggableElement">
|
||||
<div class="indexpage-container-box">
|
||||
<img :src="imgUrl" alt="" class="indexpage-container-box-img" />
|
||||
|
||||
<div class="indexpage-container-box-point">
|
||||
<div
|
||||
<!-- 连线 -->
|
||||
<!-- <div
|
||||
class="line-box"
|
||||
v-for="(item, index) in lineList"
|
||||
:key="index"
|
||||
@ -48,6 +49,19 @@
|
||||
transformOrigin: 'left top'
|
||||
}"
|
||||
>
|
||||
</div> -->
|
||||
<!-- 小车 -->
|
||||
<div class="indexpage-car-item"
|
||||
v-for="(item, index) in testCarList"
|
||||
@dblclick="carDbClick(item,index)"
|
||||
:key="index"
|
||||
:style="{
|
||||
left: item.realX * radio + 'px',
|
||||
top: item.realY * radio + 'px',
|
||||
width: 40 * radio + 'px',
|
||||
height: 22 * radio + 'px',
|
||||
}">
|
||||
<img src="@/assets/imgs/indexPage/chache-4备份 7@2x.png" alt="" style="width: 100%; height: 100%" />
|
||||
</div>
|
||||
<div
|
||||
class="indexpage-container-box-point-item"
|
||||
@ -107,14 +121,6 @@
|
||||
{{ item.showData.areaName || '' }}
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="indexpage-container-box-point-item-inner-popover-item" style="margin-bottom: 8px;">
|
||||
<div class="indexpage-container-box-point-item-inner-popover-name">
|
||||
状态:
|
||||
</div>
|
||||
<div class="indexpage-container-box-point-item-inner-popover-value">
|
||||
{{ item.showData.locationUseStatus == 0 ? '空闲' : '占用' }}
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
</el-popover>
|
||||
</div>
|
||||
@ -130,6 +136,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<storeDialog ref="storeDialogRef" @success="getList" />
|
||||
<carDialog ref="carDialogRef" />
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
@ -139,14 +146,33 @@ import WebSocketClient from '../webSocket.js'
|
||||
import storeDialog from './storeDialog.vue'
|
||||
import { color } from 'echarts'
|
||||
import { resetDragPosition } from '@/utils/drag'
|
||||
import carDialog from './carDialog.vue'
|
||||
const imgUrl = ref('')
|
||||
|
||||
const carDialogRef = ref(null)
|
||||
const socketClient = ref(null)
|
||||
|
||||
const emit = defineEmits(['transmitMapId'])
|
||||
const storeDialogRef = ref(null)
|
||||
const list = ref([])
|
||||
const nowObject = ref(null)
|
||||
const testCarList = ref([])
|
||||
const carPointListFun = () => {
|
||||
let testJson = {"type":"map_push","content":"{\"d0:65:78:c4:af:cc\":\"{\\\"id\\\":1,\\\"macAddress\\\":\\\"d0:65:78:c4:af:cc\\\",\\\"robotModelNumber\\\":\\\"A-1\\\",\\\"pose2d\\\":{\\\"y\\\":\\\"1\\\",\\\"x\\\":\\\"2\\\",\\\"yaw\\\":\\\"30\\\",\\\"floor\\\":\\\"1\\\",\\\"area\\\":\\\"A区\\\",\\\"bat_soc\\\":\\\"40\\\"}}\"}"}
|
||||
let data = JSON.parse(testJson.content)
|
||||
// console.log("============",data)
|
||||
let dataList = []
|
||||
for (let key in data) {
|
||||
dataList.push({
|
||||
macAddress: key,
|
||||
data: JSON.parse(data[key])
|
||||
})
|
||||
}
|
||||
console.log("=====",dataList)
|
||||
testCarList.value = dataList
|
||||
|
||||
// let data2 = JSON.parse(data['d0:65:78:c4:af:cc'])
|
||||
// console.log(data2)
|
||||
}
|
||||
//获取地图区域
|
||||
const getList = async () => {
|
||||
let data = await MapApi.getPositionMapGetMap()
|
||||
@ -154,9 +180,22 @@ const getList = async () => {
|
||||
for (let key in data) {
|
||||
mapList.push({
|
||||
floor: key,
|
||||
label: key + '层',
|
||||
value: key,
|
||||
children: data[key]
|
||||
})
|
||||
}
|
||||
if(mapList.length){
|
||||
mapList.forEach(item => {
|
||||
if(item.children.length){
|
||||
item.children.forEach(child => {
|
||||
child.label = child.area
|
||||
child.value = child.id
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
list.value = mapList
|
||||
console.log(list.value, data)
|
||||
//默认取第一个
|
||||
@ -280,6 +319,7 @@ const disconnect = () => {
|
||||
}
|
||||
//获取扫描图
|
||||
const getMapData = async (item) => {
|
||||
console.log("============",item)
|
||||
nowObject.value = JSON.parse(JSON.stringify(item))
|
||||
let websoketUrl = `${replaceHttpWithWs(import.meta.env.VITE_BASE_URL)}/infra/ws?type=map&floor=${nowObject.value.floor}&area=${nowObject.value.area}`
|
||||
console.log(websoketUrl)
|
||||
@ -298,20 +338,48 @@ const getMapData = async (item) => {
|
||||
computedRatio()
|
||||
}
|
||||
const heightVal = ref(0)
|
||||
const widthVal = ref(0)
|
||||
const radio = ref(1)
|
||||
const computedRatio = () => {
|
||||
nextTick(() => {
|
||||
if (imgUrl.value) {
|
||||
|
||||
//这段代码之后会删掉 yaml会给原始宽高
|
||||
getImageSize(imgUrl.value)
|
||||
.then(({ width, height }) => {
|
||||
// console.log("原始地图的宽高",JSON.parse(nowObject.value.yamlJson))
|
||||
if(testCarList.value.length){
|
||||
testCarList.value.forEach((item) => {
|
||||
item.originWidth = width
|
||||
item.originHeight = height
|
||||
item.origin = JSON.parse(nowObject.value.yamlJson).origin
|
||||
item.realX = convertToFrontendCoordinates(item.origin, width, height, [item.data.pose2d.x, item.data.pose2d.y]).left
|
||||
item.realY = convertToFrontendCoordinates(item.origin, width, height, [item.data.pose2d.x, item.data.pose2d.y]).top
|
||||
})
|
||||
console.log("当前数据",testCarList.value)
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(error.message);
|
||||
});
|
||||
|
||||
let width = getElementWidthByClass('indexpage-container')
|
||||
getImageWidth(imgUrl.value,'width').then((res) => {
|
||||
// console.log(res)
|
||||
let ratioVal = width / res
|
||||
radio.value = ratioVal
|
||||
widthVal.value = res
|
||||
if (pointList.value.length) {
|
||||
pointList.value.forEach((item) => {
|
||||
item.radio = radio.value
|
||||
})
|
||||
}
|
||||
if(testCarList.value.length){
|
||||
testCarList.value.forEach((item) => {
|
||||
item.radio = radio.value
|
||||
|
||||
})
|
||||
}
|
||||
})
|
||||
getImageWidth(imgUrl.value,'height').then((res) => {
|
||||
console.log("高",res)
|
||||
@ -322,6 +390,44 @@ const computedRatio = () => {
|
||||
})
|
||||
}
|
||||
|
||||
const getImageSize = (url) =>{
|
||||
return new Promise((resolve, reject) => {
|
||||
const img = new Image();
|
||||
img.src = url;
|
||||
// 图片加载成功时触发
|
||||
img.onload = () => {
|
||||
const width = img.width;
|
||||
const height = img.height;
|
||||
resolve({ width, height });
|
||||
};
|
||||
// 图片加载失败时触发
|
||||
img.onerror = () => {
|
||||
reject(new Error(`Failed to load image from URL 获取图片尺寸失败: ${url}`));
|
||||
};
|
||||
});
|
||||
}
|
||||
const convertToFrontendCoordinates = (origin, width, height, target) => {
|
||||
// 提取原点的 x 和 y 坐标
|
||||
const [originX, originY] = origin;
|
||||
// 提取目标点的 x 和 y 坐标
|
||||
const [targetX, targetY] = target;
|
||||
|
||||
// 计算目标点相对于原点在 x 方向上的偏移量
|
||||
const offsetX = targetX - originX;
|
||||
// 计算目标点相对于原点在 y 方向上的偏移量
|
||||
const offsetY = targetY - originY;
|
||||
|
||||
// 计算前端页面中的 left 坐标
|
||||
const left = offsetX;
|
||||
// 计算前端页面中的 top 坐标,需要考虑坐标系的转换
|
||||
const top = height - offsetY;
|
||||
|
||||
return {
|
||||
top,
|
||||
left,
|
||||
origin
|
||||
};
|
||||
}
|
||||
const getImageWidth = (imageUrl,name) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const img = new Image()
|
||||
@ -344,9 +450,15 @@ const getElementWidthByClass = (className) => {
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
//小车双击
|
||||
const carDbClick = (item,index) => {
|
||||
console.log(item)
|
||||
carDialogRef.value.open(JSON.parse(JSON.stringify(item)))
|
||||
}
|
||||
defineExpose({ getMapData }) // 提供 open 方法,用于打开弹窗
|
||||
onMounted(() => {
|
||||
getList()
|
||||
carPointListFun()
|
||||
// getList()
|
||||
window.addEventListener('resize', computedRatio)
|
||||
})
|
||||
onBeforeUnmount(() => {
|
||||
@ -359,6 +471,7 @@ onBeforeUnmount(() => {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
background: rgba(0,0,0,0.8);
|
||||
}
|
||||
.indexpage-container {
|
||||
width: 100%;
|
||||
@ -430,4 +543,8 @@ onBeforeUnmount(() => {
|
||||
.line-box {
|
||||
position: absolute;
|
||||
}
|
||||
.indexpage-car-item {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
|
@ -1,14 +1,25 @@
|
||||
<template>
|
||||
<ContentWrap>
|
||||
<el-button type="success" @click="createTask">新建任务</el-button>
|
||||
<el-button type="primary" @click="editMap">地图编辑</el-button>
|
||||
<el-button type="danger" @click="emergencyStop">一键急停</el-button>
|
||||
<div style="display: flex; align-items: center">
|
||||
<el-cascader
|
||||
v-model="mapValue"
|
||||
:options="list"
|
||||
@change="handleChangeMap"
|
||||
style="width: 160px"
|
||||
/>
|
||||
<div style="width: 1px; height: 25px; background: #e5e5e5; margin: 0 16px"></div>
|
||||
<el-button @click="createTask" :icon="'CirclePlus'" style="color: #536387"
|
||||
>新建任务</el-button
|
||||
>
|
||||
<el-button @click="editMap" :icon="'EditPen'" style="color: #536387">地图编辑</el-button>
|
||||
<el-button type="danger" @click="emergencyStop" :icon="'Remove'">一键急停</el-button>
|
||||
</div>
|
||||
</ContentWrap>
|
||||
|
||||
<div class="main-content">
|
||||
<!-- <div @click="downAgv">导出zip</div> -->
|
||||
<!-- 首页 -->
|
||||
<indexPage ref="indexPageRef" @transmitMapInfo="transmitMapInfo" />
|
||||
<indexPage ref="indexPageRef" />
|
||||
</div>
|
||||
|
||||
<!-- 新建任务的弹窗 -->
|
||||
@ -22,16 +33,102 @@ import { ref, defineComponent, reactive, nextTick, onMounted } from 'vue'
|
||||
import * as MapApi from '@/api/map/map'
|
||||
import download from '@/utils/download'
|
||||
|
||||
|
||||
defineOptions({ name: 'MapPageRealTimeMap' })
|
||||
|
||||
const mapValue = ref([])
|
||||
const list = ref([])
|
||||
const indexPageRef = ref(null)
|
||||
|
||||
const downAgv = async () => {
|
||||
const data = await MapApi.agvDownload()
|
||||
download.zip(data, `agv-${new Date().getTime()}.zip`)
|
||||
}
|
||||
const findChildrenByValues = (tree, values) => {
|
||||
if (!tree || tree.length === 0) {
|
||||
return null
|
||||
}
|
||||
function traverse(node) {
|
||||
if (node.children) {
|
||||
for (let child of node.children) {
|
||||
if (values.includes(child.value)) {
|
||||
return child;
|
||||
}
|
||||
let result = traverse(child);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
for (let root of tree) {
|
||||
if (values.includes(root.value)) {
|
||||
if (root.children) {
|
||||
for (let child of root.children) {
|
||||
if (values.includes(child.value)) {
|
||||
return child;
|
||||
}
|
||||
let result = traverse(child);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let result = traverse(root);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
//获取地图区域
|
||||
const getList = async () => {
|
||||
let data = await MapApi.getPositionMapGetMap()
|
||||
let mapList = []
|
||||
for (let key in data) {
|
||||
mapList.push({
|
||||
floor: key,
|
||||
label: key + '层',
|
||||
value: key,
|
||||
children: data[key]
|
||||
})
|
||||
}
|
||||
if (mapList.length) {
|
||||
mapList.forEach((item) => {
|
||||
if (item.children.length) {
|
||||
item.children.forEach((child) => {
|
||||
child.label = child.area
|
||||
child.value = child.id
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
list.value = mapList
|
||||
console.log(list.value, data)
|
||||
mapValue.value = [list.value[0].value, list.value[0].children[0].value]
|
||||
mapInfo.value = list.value[0].children[0]
|
||||
? JSON.parse(JSON.stringify(list.value[0].children[0]))
|
||||
: {
|
||||
mapId: '',
|
||||
floor: '',
|
||||
area: ''
|
||||
}
|
||||
indexPageRef.value.getMapData(mapInfo.value)
|
||||
}
|
||||
const handleChangeMap = async (e) => {
|
||||
mapInfo.value = findChildrenByValues(list.value, e)
|
||||
? findChildrenByValues(list.value, e)
|
||||
: {
|
||||
mapId: '',
|
||||
floor: '',
|
||||
area: ''
|
||||
}
|
||||
console.log(mapInfo.value)
|
||||
indexPageRef.value.getMapData(mapInfo.value)
|
||||
}
|
||||
//新建任务
|
||||
const createTaskDialogRef = ref()
|
||||
const createTask = () => {
|
||||
@ -60,9 +157,13 @@ const mapInfo = ref({
|
||||
floor: '',
|
||||
area: ''
|
||||
})
|
||||
const transmitMapInfo = (map) => {
|
||||
mapInfo.value = map
|
||||
}
|
||||
// const transmitMapInfo = (map) => {
|
||||
// mapInfo.value = map
|
||||
// }
|
||||
|
||||
onMounted(() => {
|
||||
getList()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
@ -17,37 +17,419 @@
|
||||
<div class="">
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="12">
|
||||
<el-card style="width: 100%;">
|
||||
<div class="charts-title">
|
||||
任务总览
|
||||
</div>
|
||||
</el-card>
|
||||
<el-card style="width: 100%">
|
||||
<div class="charts-title"> 任务总览 </div>
|
||||
<div ref="chartDom" style="width: 100%; height: 400px"></div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-card style="width: 100%">
|
||||
<div class="charts-title">
|
||||
任务总览
|
||||
</div>
|
||||
</el-card>
|
||||
<div class="charts-title"> 任务完成率 </div>
|
||||
<div ref="chartDomFinish" style="width: 100%; height: 400px"></div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="16" style="margin-top: 12px">
|
||||
<el-col :span="12">
|
||||
<el-card style="width: 100%;">
|
||||
111
|
||||
</el-card>
|
||||
<el-card style="width: 100%">
|
||||
<div class="charts-title"> AGV工作利用率统计 </div>
|
||||
<div ref="chartDomAgv" style="width: 100%; height: 400px"></div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-card style="width: 100%;">
|
||||
111
|
||||
</el-card>
|
||||
<el-card style="width: 100%">
|
||||
<div class="charts-title"> 任务异常数 </div>
|
||||
<div ref="chartDomError" style="width: 100%; height: 400px"></div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, onMounted, onBeforeUnmount } from 'vue'
|
||||
import { ref, onMounted, onUnmounted, nextTick, reactive } from 'vue'
|
||||
import * as echarts from 'echarts'
|
||||
import { lte } from 'lodash-es'
|
||||
|
||||
// 创建一个响应式引用来保存DOM元素
|
||||
const chartDom = ref(null)
|
||||
const chartDomFinish = ref(null)
|
||||
const chartDomError = ref(null)
|
||||
const chartDomAgv = ref(null)
|
||||
|
||||
// 初始化ECharts实例并设置配置项(这里以折线图为例,但可灵活替换)
|
||||
onMounted(async () => {
|
||||
await nextTick() // 确保DOM已经渲染完成
|
||||
initEcharts()
|
||||
})
|
||||
|
||||
const initEcharts = () => {
|
||||
initOne()
|
||||
initTwo()
|
||||
initFour()
|
||||
}
|
||||
|
||||
const chartInstance = ref(null)
|
||||
const initOne = () => {
|
||||
chartInstance.value = echarts.init(chartDom.value)
|
||||
let ydata = [
|
||||
{
|
||||
name: '执行中',
|
||||
value: 18
|
||||
},
|
||||
{
|
||||
name: '已完成',
|
||||
value: 16
|
||||
},
|
||||
{
|
||||
name: '已取消',
|
||||
value: 15
|
||||
},
|
||||
{
|
||||
name: '未开始',
|
||||
value: 14
|
||||
},
|
||||
{
|
||||
name: '异常',
|
||||
value: 10
|
||||
}
|
||||
]
|
||||
let color = ['#0147EB', '#01BCEB', '#C800FF', '#F1CD0B', '#EB0000']
|
||||
let xdata = ['执行中', '已完成', '已取消', '未开始', '异常']
|
||||
const option = {
|
||||
backgroundColor: 'rgba(255,255,255,1)',
|
||||
color: color,
|
||||
// tooltip: {
|
||||
// trigger: 'item',
|
||||
// // formatter: '{a} <br/>{b} : {c} ({d}%)'
|
||||
// },
|
||||
legend: {
|
||||
orient: 'vartical',
|
||||
x: 'left',
|
||||
top: 'center',
|
||||
left: '60%',
|
||||
bottom: '0%',
|
||||
data: xdata,
|
||||
itemWidth: 10,
|
||||
itemHeight: 10,
|
||||
itemGap: 16,
|
||||
formatter: function (name) {
|
||||
let str = ''
|
||||
ydata.forEach((item) => {
|
||||
if (item.name == name) {
|
||||
str = `{c|${item.name}} {a|${item.value}}`
|
||||
}
|
||||
})
|
||||
return str
|
||||
},
|
||||
textStyle: {
|
||||
rich: {
|
||||
a: {
|
||||
color: '#0D162A',
|
||||
fontSize: 18
|
||||
},
|
||||
c: {
|
||||
color: '#536387',
|
||||
fontSize: 12
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'pie',
|
||||
clockwise: false, //饼图的扇区是否是顺时针排布
|
||||
minAngle: 2, //最小的扇区角度(0 ~ 360)
|
||||
radius: ['50%', '65%'],
|
||||
center: ['30%', '50%'],
|
||||
avoidLabelOverlap: false,
|
||||
itemStyle: {
|
||||
//图形样式
|
||||
normal: {
|
||||
borderColor: '#ffffff',
|
||||
borderWidth: 6
|
||||
}
|
||||
},
|
||||
label: {
|
||||
// '{text|{b}}\n{c} ({d}%)'
|
||||
normal: {
|
||||
show: true,
|
||||
position: 'center',
|
||||
formatter: '{c|234,12} \n {a|任务总数}',
|
||||
rich: {
|
||||
c: {
|
||||
color: '#0D162A',
|
||||
fontSize: 15,
|
||||
fontWeight: 'bold',
|
||||
height: 30
|
||||
},
|
||||
|
||||
a: {
|
||||
align: 'center',
|
||||
color: '#727272',
|
||||
fontSize: 12
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
labelLine: {
|
||||
length: 15,
|
||||
length2: 0,
|
||||
maxSurfaceAngle: 80
|
||||
},
|
||||
data: ydata
|
||||
}
|
||||
]
|
||||
}
|
||||
chartInstance.value.setOption(option)
|
||||
}
|
||||
|
||||
const chartInstanceTwo = ref(null)
|
||||
const initTwo = () => {
|
||||
chartInstanceTwo.value = echarts.init(chartDomFinish.value)
|
||||
let option = {
|
||||
backgroundColor: '#fff',
|
||||
grid: {
|
||||
top: '9%',
|
||||
bottom: '19%',
|
||||
left: '6%',
|
||||
right: '4%'
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
label: {
|
||||
show: true
|
||||
}
|
||||
},
|
||||
xAxis: {
|
||||
boundaryGap: true, //默认,坐标轴留白策略
|
||||
axisLine: {
|
||||
show: false
|
||||
},
|
||||
splitLine: {
|
||||
show: false
|
||||
},
|
||||
axisTick: {
|
||||
show: false,
|
||||
alignWithLabel: true
|
||||
},
|
||||
data: [
|
||||
'武汉',
|
||||
'襄阳',
|
||||
'黄冈',
|
||||
'荆门',
|
||||
'十堰',
|
||||
'随州',
|
||||
'鄂州',
|
||||
'恩施',
|
||||
'宜昌',
|
||||
'孝感',
|
||||
'咸宁',
|
||||
'仙桃',
|
||||
'潜江',
|
||||
'天门',
|
||||
'黄石',
|
||||
'荆州',
|
||||
'神农架'
|
||||
]
|
||||
},
|
||||
yAxis: {
|
||||
axisLine: {
|
||||
show: false
|
||||
},
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
type: 'solid',
|
||||
color: '#E2E7F5'
|
||||
}
|
||||
},
|
||||
axisTick: {
|
||||
show: false
|
||||
},
|
||||
splitArea: {
|
||||
show: true,
|
||||
areaStyle: {
|
||||
color: 'rgb(245,250,254)'
|
||||
}
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'line',
|
||||
symbol: 'circle',
|
||||
symbolSize: 1,
|
||||
lineStyle: {
|
||||
color: '#0147EB'
|
||||
},
|
||||
|
||||
label: {
|
||||
show: false,
|
||||
distance: 1,
|
||||
emphasis: {
|
||||
show: true,
|
||||
offset: [25, -2],
|
||||
backgroundColor: 'rgba(0,0,0,0.7)',
|
||||
color: '#FFF',
|
||||
padding: [8, 20, 8, 6],
|
||||
//width:60,
|
||||
height: 36,
|
||||
formatter: function (params) {
|
||||
var name = params.name
|
||||
var value = params.data
|
||||
var str = name + '\n数据量:' + value
|
||||
return str
|
||||
},
|
||||
rich: {
|
||||
bg: {
|
||||
width: 78,
|
||||
//height:42,
|
||||
color: '#FFF',
|
||||
padding: [20, 0, 20, 10]
|
||||
},
|
||||
br: {
|
||||
width: '100%',
|
||||
height: '100%'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
data: [
|
||||
2000, 1800, 2800, 900, 1600, 2000, 3000, 2030, 1356, 1900, 4000, 3000, 2000, 3000, 4200,
|
||||
3200, 3800
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
chartInstanceTwo.value.setOption(option)
|
||||
}
|
||||
|
||||
const chartInstanceFour = ref(null)
|
||||
const initFour = () => {
|
||||
chartInstanceFour.value = echarts.init(chartDomError.value)
|
||||
let option = {
|
||||
backgroundColor: '#fff',
|
||||
grid: {
|
||||
top: '9%',
|
||||
bottom: '19%',
|
||||
left: '6%',
|
||||
right: '4%'
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
label: {
|
||||
show: true
|
||||
}
|
||||
},
|
||||
xAxis: {
|
||||
boundaryGap: true, //默认,坐标轴留白策略
|
||||
axisLine: {
|
||||
show: false
|
||||
},
|
||||
splitLine: {
|
||||
show: false
|
||||
},
|
||||
axisTick: {
|
||||
show: false,
|
||||
alignWithLabel: true
|
||||
},
|
||||
data: [
|
||||
'武汉',
|
||||
'襄阳',
|
||||
'黄冈',
|
||||
'荆门',
|
||||
'十堰',
|
||||
'随州',
|
||||
'鄂州',
|
||||
'恩施',
|
||||
'宜昌',
|
||||
'孝感',
|
||||
'咸宁',
|
||||
'仙桃',
|
||||
'潜江',
|
||||
'天门',
|
||||
'黄石',
|
||||
'荆州',
|
||||
'神农架'
|
||||
]
|
||||
},
|
||||
yAxis: {
|
||||
axisLine: {
|
||||
show: false
|
||||
},
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
type: 'solid',
|
||||
color: '#E2E7F5'
|
||||
}
|
||||
},
|
||||
axisTick: {
|
||||
show: false
|
||||
},
|
||||
splitArea: {
|
||||
show: true,
|
||||
areaStyle: {
|
||||
color: 'rgb(245,250,254)'
|
||||
}
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
type: 'line',
|
||||
symbol: 'circle',
|
||||
symbolSize: 1,
|
||||
lineStyle: {
|
||||
color: '#0147EB'
|
||||
},
|
||||
|
||||
label: {
|
||||
show: false,
|
||||
distance: 1,
|
||||
emphasis: {
|
||||
show: true,
|
||||
offset: [25, -2],
|
||||
backgroundColor: 'rgba(0,0,0,0.7)',
|
||||
color: '#FFF',
|
||||
padding: [8, 20, 8, 6],
|
||||
//width:60,
|
||||
height: 36,
|
||||
formatter: function (params) {
|
||||
var name = params.name
|
||||
var value = params.data
|
||||
var str = name + '\n数据量:' + value
|
||||
return str
|
||||
},
|
||||
rich: {
|
||||
bg: {
|
||||
width: 78,
|
||||
//height:42,
|
||||
color: '#FFF',
|
||||
padding: [20, 0, 20, 10]
|
||||
},
|
||||
br: {
|
||||
width: '100%',
|
||||
height: '100%'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
data: [
|
||||
2000, 1800, 2800, 900, 1600, 2000, 3000, 2030, 1356, 1900, 4000, 3000, 2000, 3000, 4200,
|
||||
3200, 3800
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
chartInstanceFour.value.setOption(option)
|
||||
}
|
||||
// 销毁ECharts实例
|
||||
onUnmounted(() => {
|
||||
if (chartInstance.value != null && chartInstance.value.dispose) {
|
||||
chartInstance.value.dispose()
|
||||
}
|
||||
})
|
||||
|
||||
const type = ref(1)
|
||||
</script>
|
||||
|
||||
|