2025-10-20 17:32:09 +08:00
|
|
|
|
<template>
|
|
|
|
|
|
<!-- 参数缺失时的友好提示 -->
|
|
|
|
|
|
<div v-if="!route.query.id" class="error-container">
|
|
|
|
|
|
<el-result
|
|
|
|
|
|
icon="warning"
|
|
|
|
|
|
title="参数缺失"
|
|
|
|
|
|
sub-title="缺少必要的参数,无法加载详情页面"
|
|
|
|
|
|
>
|
|
|
|
|
|
<template #extra>
|
|
|
|
|
|
<el-button type="primary" @click="goBack">返回上一页</el-button>
|
|
|
|
|
|
<el-button @click="goToList">前往列表页面</el-button>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</el-result>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 正常内容 -->
|
|
|
|
|
|
<section v-else>
|
|
|
|
|
|
<div class="main-container">
|
|
|
|
|
|
<div class="info-box">
|
|
|
|
|
|
<div class="title">基础信息</div>
|
|
|
|
|
|
<el-descriptions :column="4">
|
|
|
|
|
|
<el-descriptions-item label="运单号:">{{ data.baseInfo.deliveryNumber || '-' }}</el-descriptions-item>
|
|
|
|
|
|
<el-descriptions-item label="订单标题:">{{ data.baseInfo.deliveryTitle || '-' }}</el-descriptions-item>
|
|
|
|
|
|
<el-descriptions-item label="资金方:">{{ data.baseInfo.fundName || '-' }}</el-descriptions-item>
|
|
|
|
|
|
<el-descriptions-item label="采购商:">{{ data.baseInfo.buyerName || '-' }}</el-descriptions-item>
|
|
|
|
|
|
<el-descriptions-item label="车牌号:">{{ data.baseInfo.licensePlate || '-' }}</el-descriptions-item>
|
|
|
|
|
|
<el-descriptions-item label="司机姓名:">{{ data.baseInfo.driverName || '-' }}</el-descriptions-item>
|
|
|
|
|
|
<el-descriptions-item label="起始地:">{{ data.baseInfo.startLocation || '-' }}</el-descriptions-item>
|
|
|
|
|
|
<el-descriptions-item label="送达目的地:">{{ data.baseInfo.endLocation || '-' }}</el-descriptions-item>
|
|
|
|
|
|
<el-descriptions-item label="预计送达时间:">{{ data.baseInfo.estimatedDeliveryTime || '-' }}</el-descriptions-item>
|
|
|
|
|
|
<el-descriptions-item label="创建时间:">{{ data.baseInfo.createTime || '' }}</el-descriptions-item>
|
2025-10-24 17:32:42 +08:00
|
|
|
|
<el-descriptions-item label="登记设备数量:">{{ totalRegisteredDevices }} 个</el-descriptions-item>
|
2025-10-20 17:32:09 +08:00
|
|
|
|
<el-descriptions-item label="状态:">
|
2025-10-27 17:38:20 +08:00
|
|
|
|
<el-tag :type="getStatusType(data.baseInfo.status)">{{ getStatusText(data.baseInfo.status) }}</el-tag>
|
2025-10-20 17:32:09 +08:00
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
|
<el-descriptions-item label="车身照片:">
|
|
|
|
|
|
<span style="vertical-align: top">
|
|
|
|
|
|
<el-image
|
|
|
|
|
|
v-if="data.baseInfo.carFrontPhoto"
|
|
|
|
|
|
style="width: 50px; height: 50px; margin-right: 10px"
|
|
|
|
|
|
:src="data.baseInfo.carFrontPhoto ? data.baseInfo.carFrontPhoto : ''"
|
|
|
|
|
|
fit="cover"
|
|
|
|
|
|
:preview-src-list="[data.baseInfo.carFrontPhoto] ? [data.baseInfo.carFrontPhoto] : []"
|
|
|
|
|
|
preview-teleported
|
|
|
|
|
|
/>
|
|
|
|
|
|
<el-image
|
|
|
|
|
|
v-if="data.baseInfo.carBehindPhoto"
|
|
|
|
|
|
style="width: 50px; height: 50px; margin-right: 10px"
|
|
|
|
|
|
:src="data.baseInfo.carBehindPhoto ? data.baseInfo.carBehindPhoto : ''"
|
|
|
|
|
|
fit="cover"
|
|
|
|
|
|
:preview-src-list="[data.baseInfo.carBehindPhoto] ? [data.baseInfo.carBehindPhoto] : []"
|
|
|
|
|
|
preview-teleported
|
|
|
|
|
|
/>
|
|
|
|
|
|
</span>
|
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
|
</el-descriptions>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="info-box" v-if="data.length != 0">
|
|
|
|
|
|
<div class="title">预警信息</div>
|
|
|
|
|
|
<el-descriptions :column="4">
|
|
|
|
|
|
<template v-for="(item, index) in data.warnInfo" :key="index">
|
|
|
|
|
|
<template v-if="item.warningType == 2">
|
|
|
|
|
|
<el-descriptions-item label="预警原因:">
|
|
|
|
|
|
<span class="red">{{ item.warningTypeDesc }}</span>
|
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
|
<el-descriptions-item label="预警时间:">{{ item.warningTime || '--' }}</el-descriptions-item>
|
2025-10-24 17:32:42 +08:00
|
|
|
|
<el-descriptions-item label="智能耳标数:"> {{ totalRegisteredDevices }} 个 </el-descriptions-item>
|
2025-10-20 17:32:09 +08:00
|
|
|
|
<el-descriptions-item label="车内盘点数量:"> {{ item.inventoryJbqCount || '--' }} 个 </el-descriptions-item>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
<template v-if="item.warningType == 3">
|
|
|
|
|
|
<el-descriptions-item label="预警原因:">
|
|
|
|
|
|
<span class="red">{{ item.warningTypeDesc || '' }}</span>
|
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
|
<el-descriptions-item label="预警时间:">{{ item.warningTime || '' }}</el-descriptions-item>
|
|
|
|
|
|
<el-descriptions-item label="应行驶距离:"> {{ item.expectedDistance || '' }} km </el-descriptions-item>
|
|
|
|
|
|
<el-descriptions-item label="实际行驶距离:"> {{ item.actualDistance || '' }} km </el-descriptions-item>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</el-descriptions>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="info-box">
|
|
|
|
|
|
<div class="title">装车信息</div>
|
|
|
|
|
|
<el-descriptions :column="4">
|
|
|
|
|
|
<!-- 重量信息 -->
|
|
|
|
|
|
<el-descriptions-item label="空车过磅重量:">{{
|
|
|
|
|
|
data.baseInfo.emptyWeight ? data.baseInfo.emptyWeight + 'kg' : ''
|
|
|
|
|
|
}}</el-descriptions-item>
|
|
|
|
|
|
<el-descriptions-item label="装车过磅重量:">{{
|
|
|
|
|
|
data.baseInfo.entruckWeight ? data.baseInfo.entruckWeight + 'kg' : ''
|
|
|
|
|
|
}}</el-descriptions-item>
|
2025-10-21 17:29:52 +08:00
|
|
|
|
<el-descriptions-item label="落地过磅重量:">{{
|
|
|
|
|
|
data.baseInfo.landingEntruckWeight ? data.baseInfo.landingEntruckWeight + 'kg' : ''
|
|
|
|
|
|
}}</el-descriptions-item>
|
2025-10-20 17:32:09 +08:00
|
|
|
|
|
|
|
|
|
|
<!-- 照片上传区域 -->
|
|
|
|
|
|
<el-descriptions-item label="检疫票:">
|
|
|
|
|
|
<span style="vertical-align: top">
|
|
|
|
|
|
<el-image
|
|
|
|
|
|
v-if="data.baseInfo.quarantineTickeyUrl"
|
|
|
|
|
|
style="width: 50px; height: 50px; margin-right: 10px"
|
|
|
|
|
|
:src="data.baseInfo.quarantineTickeyUrl ? data.baseInfo.quarantineTickeyUrl : ''"
|
|
|
|
|
|
fit="cover"
|
|
|
|
|
|
:preview-src-list="[data.baseInfo.quarantineTickeyUrl] ? [data.baseInfo.quarantineTickeyUrl] : []"
|
|
|
|
|
|
preview-teleported
|
|
|
|
|
|
/>
|
|
|
|
|
|
</span>
|
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
|
<el-descriptions-item label="纸质磅单:">
|
|
|
|
|
|
<span style="vertical-align: top">
|
|
|
|
|
|
<el-image
|
|
|
|
|
|
v-if="data.baseInfo.poundListImg"
|
|
|
|
|
|
style="width: 50px; height: 50px; margin-right: 10px"
|
|
|
|
|
|
:src="data.baseInfo.poundListImg ? data.baseInfo.poundListImg : ''"
|
|
|
|
|
|
fit="cover"
|
|
|
|
|
|
:preview-src-list="[data.baseInfo.poundListImg] ? [data.baseInfo.poundListImg] : []"
|
|
|
|
|
|
preview-teleported
|
|
|
|
|
|
/>
|
|
|
|
|
|
</span>
|
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
|
<el-descriptions-item label="车辆空磅上磅车头照片:">
|
|
|
|
|
|
<span style="vertical-align: top">
|
|
|
|
|
|
<el-image
|
|
|
|
|
|
v-if="data.baseInfo.emptyVehicleFrontPhoto"
|
|
|
|
|
|
style="width: 50px; height: 50px; margin-right: 10px"
|
|
|
|
|
|
:src="data.baseInfo.emptyVehicleFrontPhoto ? data.baseInfo.emptyVehicleFrontPhoto : ''"
|
|
|
|
|
|
fit="cover"
|
|
|
|
|
|
:preview-src-list="[data.baseInfo.emptyVehicleFrontPhoto] ? [data.baseInfo.emptyVehicleFrontPhoto] : []"
|
|
|
|
|
|
preview-teleported
|
|
|
|
|
|
/>
|
|
|
|
|
|
</span>
|
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
|
<el-descriptions-item label="车辆过重磅车头照片:">
|
|
|
|
|
|
<span style="vertical-align: top">
|
|
|
|
|
|
<el-image
|
|
|
|
|
|
v-if="data.baseInfo.loadedVehicleFrontPhoto"
|
|
|
|
|
|
style="width: 50px; height: 50px; margin-right: 10px"
|
|
|
|
|
|
:src="data.baseInfo.loadedVehicleFrontPhoto ? data.baseInfo.loadedVehicleFrontPhoto : ''"
|
|
|
|
|
|
fit="cover"
|
|
|
|
|
|
:preview-src-list="[data.baseInfo.loadedVehicleFrontPhoto] ? [data.baseInfo.loadedVehicleFrontPhoto] : []"
|
|
|
|
|
|
preview-teleported
|
|
|
|
|
|
/>
|
|
|
|
|
|
</span>
|
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
|
<el-descriptions-item label="车辆重磅照片:">
|
|
|
|
|
|
<span style="vertical-align: top">
|
|
|
|
|
|
<el-image
|
|
|
|
|
|
v-if="data.baseInfo.loadedVehicleWeightPhoto"
|
|
|
|
|
|
style="width: 50px; height: 50px; margin-right: 10px"
|
|
|
|
|
|
:src="data.baseInfo.loadedVehicleWeightPhoto ? data.baseInfo.loadedVehicleWeightPhoto : ''"
|
|
|
|
|
|
fit="cover"
|
|
|
|
|
|
:preview-src-list="[data.baseInfo.loadedVehicleWeightPhoto] ? [data.baseInfo.loadedVehicleWeightPhoto] : []"
|
|
|
|
|
|
preview-teleported
|
|
|
|
|
|
/>
|
|
|
|
|
|
</span>
|
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
|
<el-descriptions-item label="驾驶员手持身份证站车头照片:">
|
|
|
|
|
|
<span style="vertical-align: top">
|
|
|
|
|
|
<el-image
|
|
|
|
|
|
v-if="data.baseInfo.driverIdCardPhoto"
|
|
|
|
|
|
style="width: 50px; height: 50px; margin-right: 10px"
|
|
|
|
|
|
:src="data.baseInfo.driverIdCardPhoto ? data.baseInfo.driverIdCardPhoto : ''"
|
|
|
|
|
|
fit="cover"
|
|
|
|
|
|
:preview-src-list="[data.baseInfo.driverIdCardPhoto] ? [data.baseInfo.driverIdCardPhoto] : []"
|
|
|
|
|
|
preview-teleported
|
|
|
|
|
|
/>
|
|
|
|
|
|
</span>
|
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 视频上传区域 -->
|
|
|
|
|
|
<el-descriptions-item label="空车过磅视频(含车牌、地磅数):">
|
|
|
|
|
|
<span style="vertical-align: top" v-if="data.baseInfo.emptyWeightVideo">
|
|
|
|
|
|
<video
|
|
|
|
|
|
style="height: 250px; width: auto; border-radius: 5px; margin-left: 60px"
|
|
|
|
|
|
controls
|
|
|
|
|
|
:src="data.baseInfo.emptyWeightVideo"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</span>
|
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
|
<el-descriptions-item label="装车过磅视频:">
|
|
|
|
|
|
<span style="vertical-align: top" v-if="data.baseInfo.entruckWeightVideo">
|
|
|
|
|
|
<video
|
|
|
|
|
|
style="height: 250px; width: auto; border-radius: 5px; margin-left: 60px"
|
|
|
|
|
|
controls
|
|
|
|
|
|
:src="data.baseInfo.entruckWeightVideo"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</span>
|
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
|
<el-descriptions-item label="装车视频:">
|
|
|
|
|
|
<span style="vertical-align: top" v-if="data.baseInfo.entruckVideo">
|
|
|
|
|
|
<video
|
|
|
|
|
|
style="height: 250px; width: auto; border-radius: 5px; margin-left: 60px"
|
|
|
|
|
|
controls
|
|
|
|
|
|
:src="data.baseInfo.entruckVideo"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</span>
|
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
|
<el-descriptions-item label="控槽视频:">
|
|
|
|
|
|
<span style="vertical-align: top" v-if="data.baseInfo.controlSlotVideo">
|
|
|
|
|
|
<video
|
|
|
|
|
|
style="height: 250px; width: auto; border-radius: 5px; margin-left: 60px"
|
|
|
|
|
|
controls
|
|
|
|
|
|
:src="data.baseInfo.controlSlotVideo"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</span>
|
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
|
<el-descriptions-item label="装完牛绕车一圈视频:">
|
|
|
|
|
|
<span style="vertical-align: top" v-if="data.baseInfo.cattleLoadingCircleVideo">
|
|
|
|
|
|
<video
|
|
|
|
|
|
style="height: 250px; width: auto; border-radius: 5px; margin-left: 60px"
|
|
|
|
|
|
controls
|
|
|
|
|
|
:src="data.baseInfo.cattleLoadingCircleVideo"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</span>
|
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
|
</el-descriptions>
|
|
|
|
|
|
</div>
|
2025-10-24 17:32:42 +08:00
|
|
|
|
<div class="ear-box">
|
2025-10-20 17:32:09 +08:00
|
|
|
|
<div class="title">智能主机</div>
|
2025-10-23 17:28:06 +08:00
|
|
|
|
<el-table
|
2025-10-24 17:32:42 +08:00
|
|
|
|
:data="data.hostRows"
|
2025-10-23 17:28:06 +08:00
|
|
|
|
border
|
2025-10-24 17:32:42 +08:00
|
|
|
|
v-loading="data.hostDataListLoading"
|
2025-10-23 17:28:06 +08:00
|
|
|
|
element-loading-text="数据加载中..."
|
|
|
|
|
|
style="width: 100%"
|
|
|
|
|
|
>
|
|
|
|
|
|
<el-table-column label="智能主机编号" prop="deviceId"></el-table-column>
|
|
|
|
|
|
<el-table-column label="设备电量" prop="battery">
|
|
|
|
|
|
<template #default="scope"> {{ scope.row.battery || scope.row.deviceVoltage || '-' }}% </template>
|
|
|
|
|
|
</el-table-column>
|
|
|
|
|
|
<el-table-column label="步数" prop="steps">
|
|
|
|
|
|
<template #default="scope"> {{ scope.row.steps || scope.row.walkSteps || '-' }}步</template>
|
|
|
|
|
|
</el-table-column>
|
|
|
|
|
|
<el-table-column label="设备温度" prop="temperature">
|
|
|
|
|
|
<template #default="scope"> {{ scope.row.temperature || scope.row.deviceTemp || '-' }}℃ </template>
|
|
|
|
|
|
</el-table-column>
|
|
|
|
|
|
<el-table-column label="数据最后更新时间" prop="time">
|
|
|
|
|
|
<template #default="scope"> {{ scope.row.time || scope.row.updateTime || scope.row.createTime || '-' }}</template>
|
|
|
|
|
|
</el-table-column>
|
|
|
|
|
|
<el-table-column label="操作" prop="">
|
|
|
|
|
|
<template #default="scope">
|
2025-10-24 17:32:42 +08:00
|
|
|
|
<el-button link type="primary" @click="hostLogClick(scope.row)">日志</el-button>
|
|
|
|
|
|
<el-button link type="primary" @click="hostTrackClick(scope.row)">运动轨迹</el-button>
|
|
|
|
|
|
<el-button link type="primary" @click="hostLocationClick(scope.row)">定位</el-button>
|
2025-10-23 17:28:06 +08:00
|
|
|
|
</template>
|
|
|
|
|
|
</el-table-column>
|
|
|
|
|
|
</el-table>
|
2025-10-24 17:32:42 +08:00
|
|
|
|
</div>
|
2025-10-20 17:32:09 +08:00
|
|
|
|
<div class="ear-box">
|
|
|
|
|
|
<div class="title">智能项圈</div>
|
|
|
|
|
|
<el-table
|
|
|
|
|
|
:data="data.collarRows"
|
|
|
|
|
|
border
|
|
|
|
|
|
v-loading="data.collarDataListLoading"
|
|
|
|
|
|
element-loading-text="数据加载中..."
|
|
|
|
|
|
style="width: 100%"
|
|
|
|
|
|
>
|
2025-10-23 17:28:06 +08:00
|
|
|
|
<el-table-column label="智能项圈编号" prop="deviceId"></el-table-column>
|
2025-10-20 17:32:09 +08:00
|
|
|
|
<el-table-column label="设备电量" prop="battery">
|
2025-10-23 17:28:06 +08:00
|
|
|
|
<template #default="scope"> {{ scope.row.battery || scope.row.deviceVoltage || '-' }}% </template>
|
2025-10-20 17:32:09 +08:00
|
|
|
|
</el-table-column>
|
|
|
|
|
|
<el-table-column label="步数" prop="steps">
|
2025-10-23 17:28:06 +08:00
|
|
|
|
<template #default="scope"> {{ scope.row.steps || scope.row.walkSteps || '-' }}步</template>
|
2025-10-20 17:32:09 +08:00
|
|
|
|
</el-table-column>
|
2025-10-24 17:32:42 +08:00
|
|
|
|
<el-table-column label="设备温度" prop="deviceTemp">
|
|
|
|
|
|
<template #default="scope"> {{ scope.row.deviceTemp || scope.row.temperature || '-' }}℃ </template>
|
2025-10-23 17:28:06 +08:00
|
|
|
|
</el-table-column>
|
|
|
|
|
|
<el-table-column label="数据最后更新时间" prop="time">
|
|
|
|
|
|
<template #default="scope"> {{ scope.row.time || scope.row.updateTime || scope.row.createTime || '-' }}</template>
|
2025-10-20 17:32:09 +08:00
|
|
|
|
</el-table-column>
|
|
|
|
|
|
<el-table-column label="操作" prop="">
|
|
|
|
|
|
<template #default="scope">
|
|
|
|
|
|
<el-button link type="primary" @click="collarLogClick(scope.row)">日志</el-button>
|
|
|
|
|
|
<el-button link type="primary" @click="collarTrackClick(scope.row)">运动轨迹</el-button>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</el-table-column>
|
|
|
|
|
|
</el-table>
|
|
|
|
|
|
<pagination
|
|
|
|
|
|
v-model:limit="collarForm.pageSize"
|
|
|
|
|
|
v-model:page="collarForm.pageNum"
|
|
|
|
|
|
:total="data.collarTotal"
|
|
|
|
|
|
@pagination="getCollarList"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div class="ear-box">
|
|
|
|
|
|
<div class="title">智能耳标</div>
|
|
|
|
|
|
<el-table :data="data.rows" border v-loading="data.dataListLoading" element-loading-text="数据加载中..." style="width: 100%">
|
|
|
|
|
|
<el-table-column label="智能耳标编号" prop="deviceId"></el-table-column>
|
2025-10-24 17:32:42 +08:00
|
|
|
|
|
|
|
|
|
|
<el-table-column label="设备电量" prop="battery">
|
|
|
|
|
|
<template #default="scope"> {{ scope.row.battery || scope.row.deviceVoltage || '-' }}% </template>
|
2025-10-20 17:32:09 +08:00
|
|
|
|
</el-table-column>
|
|
|
|
|
|
<el-table-column label="步数" prop="walkSteps">
|
2025-10-23 17:28:06 +08:00
|
|
|
|
<template #default="scope"> {{ scope.row.walkSteps || scope.row.steps || '-' }}步</template>
|
2025-10-20 17:32:09 +08:00
|
|
|
|
</el-table-column>
|
|
|
|
|
|
<el-table-column label="设备温度" prop="deviceTemp">
|
2025-10-23 17:28:06 +08:00
|
|
|
|
<template #default="scope"> {{ scope.row.deviceTemp || scope.row.temperature || '-' }}℃ </template>
|
|
|
|
|
|
</el-table-column>
|
|
|
|
|
|
<el-table-column label="数据最后更新时间" prop="updateTime">
|
|
|
|
|
|
<template #default="scope"> {{ scope.row.updateTime || scope.row.createTime || '-' }}</template>
|
2025-10-20 17:32:09 +08:00
|
|
|
|
</el-table-column>
|
|
|
|
|
|
<el-table-column label="操作" prop="">
|
|
|
|
|
|
<template #default="scope">
|
|
|
|
|
|
<el-button link type="primary" @click="earLogClick(scope.row)">日志</el-button>
|
2025-10-24 17:32:42 +08:00
|
|
|
|
<el-button link type="primary" @click="earTrackClick(scope.row)">运动轨迹</el-button>
|
2025-10-20 17:32:09 +08:00
|
|
|
|
</template>
|
|
|
|
|
|
</el-table-column>
|
|
|
|
|
|
</el-table>
|
|
|
|
|
|
<pagination v-model:limit="form.pageSize" v-model:page="form.pageNum" :total="data.total" @pagination="getEarList" />
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<!-- <div class="info-box" v-if="data.status == 4 || data.status == 5">
|
|
|
|
|
|
<div class="title">核验信息</div>
|
|
|
|
|
|
<el-descriptions :column="4">
|
|
|
|
|
|
<el-descriptions-item label="到货核验人:">{{ data.baseInfo.checkByName || '' }}</el-descriptions-item>
|
|
|
|
|
|
<el-descriptions-item label="核验时间:">{{ data.baseInfo.checkTime || '' }}</el-descriptions-item>
|
|
|
|
|
|
<el-descriptions-item label="核验空车过磅重量:">{{
|
|
|
|
|
|
data.baseInfo.checkEmptyWeight ? data.baseInfo.checkEmptyWeight + 'kg' : ''
|
|
|
|
|
|
}}</el-descriptions-item>
|
|
|
|
|
|
<el-descriptions-item label="核验满车过磅重量:">{{
|
|
|
|
|
|
data.baseInfo.checkEntruckWeight ? data.baseInfo.checkEntruckWeight + 'kg' : ''
|
|
|
|
|
|
}}</el-descriptions-item>
|
|
|
|
|
|
<el-descriptions-item label="核验空车过磅视频:">
|
|
|
|
|
|
<span style="vertical-align: top" v-if="data.baseInfo.checkEmptyWeightVideo">
|
|
|
|
|
|
<video
|
|
|
|
|
|
style="height: 250px; width: auto; border-radius: 5px; margin-left: 60px"
|
|
|
|
|
|
controls
|
|
|
|
|
|
:src="data.baseInfo.checkEmptyWeightVideo"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</span>
|
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
|
<el-descriptions-item label="核验装车过磅视频:">
|
|
|
|
|
|
<span style="vertical-align: top" v-if="data.baseInfo.checkEntruckWeightVideo">
|
|
|
|
|
|
<video
|
|
|
|
|
|
style="height: 250px; width: auto; border-radius: 5px; margin-left: 60px"
|
|
|
|
|
|
controls
|
|
|
|
|
|
:src="data.baseInfo.checkEntruckWeightVideo"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</span>
|
|
|
|
|
|
</el-descriptions-item>
|
|
|
|
|
|
</el-descriptions>
|
|
|
|
|
|
</div> -->
|
|
|
|
|
|
<div class="btn-box">
|
|
|
|
|
|
<el-button @click="cancelClick">返回</el-button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<!-- 查看主机定位 -->
|
|
|
|
|
|
<el-dialog v-model="data.dialogVisible" title="查看定位" style="width: 650px; padding-bottom: 20px">
|
|
|
|
|
|
<div>
|
|
|
|
|
|
<baidu-map style="height: 500px" class="map" :zoom="15" :center="data.center" :scroll-wheel-zoom="true" v-if="data.dialogVisible">
|
|
|
|
|
|
<bm-map-type :map-types="['BMAP_NORMAL_MAP', 'BMAP_HYBRID_MAP']"></bm-map-type>
|
|
|
|
|
|
<bm-marker :position="data.center" :dragging="true" animation="BMAP_ANIMATION_BOUNCE">
|
|
|
|
|
|
<bm-label
|
|
|
|
|
|
:content="data.updateTime"
|
|
|
|
|
|
:labelStyle="{
|
|
|
|
|
|
color: '#67c23a',
|
|
|
|
|
|
fontSize: '12px',
|
|
|
|
|
|
borderColor: '#fff',
|
|
|
|
|
|
borderRadius: 10,
|
|
|
|
|
|
}"
|
|
|
|
|
|
:offset="{ width: -60, height: 10 }"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</bm-marker>
|
|
|
|
|
|
</baidu-map>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<template #footer>
|
|
|
|
|
|
<span class="dialog-footer">
|
|
|
|
|
|
<!-- <el-button @click="cancelClick">取消</el-button> -->
|
|
|
|
|
|
</span>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</el-dialog>
|
|
|
|
|
|
<!-- 查看轨迹 -->
|
|
|
|
|
|
<el-dialog v-model="data.trackDialogVisible" title="查看运动轨迹" style="width: 650px; padding-bottom: 20px">
|
|
|
|
|
|
<div
|
|
|
|
|
|
v-loading="data.trackLoading"
|
|
|
|
|
|
element-loading-text="正在加载中..."
|
|
|
|
|
|
style="height: 450px"
|
|
|
|
|
|
element-loading-background="rgba(255, 255, 255,1)"
|
|
|
|
|
|
>
|
|
|
|
|
|
<div class="empty-box" v-if="data.trajectoryStatus">
|
|
|
|
|
|
<img style="width: 50%" src="../../assets/images/wuguiji.png" />
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<baidu-map
|
|
|
|
|
|
v-else
|
|
|
|
|
|
class="map"
|
|
|
|
|
|
@ready="handler"
|
|
|
|
|
|
:center="data.centerPoint"
|
|
|
|
|
|
:zoom="data.trackZoom"
|
|
|
|
|
|
:dragging="true"
|
|
|
|
|
|
:auto-resize="true"
|
|
|
|
|
|
:scroll-wheel-zoom="true"
|
|
|
|
|
|
style="height: 450px"
|
|
|
|
|
|
>
|
|
|
|
|
|
<!-- 运行轨迹的路线 stroke-weight边线的宽度stroke-opacity边线透明度-->
|
|
|
|
|
|
<bm-polyline stroke-color="blue" :path="data.path" :stroke-opacity="0.5" :stroke-weight="3" :editing="false"></bm-polyline>
|
|
|
|
|
|
<!-- marker 可以展示的图标 起点、终点 -->
|
|
|
|
|
|
<bm-marker :icon="startMarkIcon" :position="{ lng: data.startMark.lng, lat: data.startMark.lat }"></bm-marker>
|
|
|
|
|
|
<bm-marker :icon="endMarkIcon" :position="{ lng: data.endMark.lng, lat: data.endMark.lat }"></bm-marker>
|
|
|
|
|
|
<!-- <bm-marker
|
|
|
|
|
|
v-for="(item, index) in data.path"
|
|
|
|
|
|
:key="index"
|
|
|
|
|
|
:icon="biaoMarkIcon"
|
|
|
|
|
|
:position="{ lng: item.lng, lat: item.lat }"
|
|
|
|
|
|
></bm-marker> -->
|
|
|
|
|
|
<!-- 暂停是根据你提供的坐标,如果还没过第一个,就会返回,如果过了,在第一个到第二个之间暂停,他会跑掉第二个后面 -->
|
|
|
|
|
|
<!-- <bml-lushu @stop="reset" :path="data.path" :icon="iconss" :play="data.play" :rotation="true" :speed="1000"></bml-lushu> -->
|
|
|
|
|
|
</baidu-map>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</el-dialog>
|
|
|
|
|
|
<!-- 耳标日志 -->
|
|
|
|
|
|
<el-dialog v-model="data.earLogDialogVisible" title="设备日志" style="width: 900px; padding-bottom: 20px">
|
|
|
|
|
|
<el-table :data="data.earLogRows" border v-loading="data.logListLoading" element-loading-text="数据加载中..." style="width: 100%">
|
|
|
|
|
|
<el-table-column label="智能耳标编号" prop="deviceId"></el-table-column>
|
|
|
|
|
|
<el-table-column label="设备电量" prop="deviceVoltage">
|
2025-10-23 17:28:06 +08:00
|
|
|
|
<template #default="scope"> {{ scope.row.deviceVoltage || scope.row.battery || '-' }}% </template>
|
2025-10-20 17:32:09 +08:00
|
|
|
|
</el-table-column>
|
|
|
|
|
|
<el-table-column label="步数" prop="walkSteps">
|
2025-10-23 17:28:06 +08:00
|
|
|
|
<template #default="scope"> {{ scope.row.walkSteps || scope.row.steps || '-' }}步</template>
|
2025-10-20 17:32:09 +08:00
|
|
|
|
</el-table-column>
|
|
|
|
|
|
<el-table-column label="设备温度" prop="deviceTemp">
|
2025-10-23 17:28:06 +08:00
|
|
|
|
<template #default="scope"> {{ scope.row.deviceTemp || scope.row.temperature || '-' }}℃ </template>
|
|
|
|
|
|
</el-table-column>
|
|
|
|
|
|
<el-table-column label="数据最后更新时间" prop="updateTime" width="200">
|
|
|
|
|
|
<template #default="scope"> {{ scope.row.updateTime || scope.row.createTime || '-' }}</template>
|
2025-10-20 17:32:09 +08:00
|
|
|
|
</el-table-column>
|
|
|
|
|
|
<el-table-column label="操作" prop="">
|
|
|
|
|
|
<template #default="scope">
|
|
|
|
|
|
<el-button link type="primary" @click="locateClick(scope.row)">定位</el-button>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</el-table-column>
|
|
|
|
|
|
</el-table>
|
|
|
|
|
|
<pagination v-model:limit="earLogForm.pageSize" v-model:page="earLogForm.pageNum" :total="data.earLogTotal" @pagination="getEarLogList" />
|
|
|
|
|
|
</el-dialog>
|
|
|
|
|
|
<!-- 项圈日志 -->
|
|
|
|
|
|
<el-dialog v-model="data.collarDialogVisible" title="设备日志" style="width: 900px; padding-bottom: 20px">
|
|
|
|
|
|
<el-table :data="data.collarLogRows" border v-loading="data.logListLoading" element-loading-text="数据加载中..." style="width: 100%">
|
2025-10-24 17:32:42 +08:00
|
|
|
|
<el-table-column label="智能项圈编号" prop="deviceId"></el-table-column>
|
2025-10-20 17:32:09 +08:00
|
|
|
|
<el-table-column label="设备电量" prop="battery">
|
2025-10-23 17:28:06 +08:00
|
|
|
|
<template #default="scope"> {{ scope.row.battery || scope.row.deviceVoltage || '-' }}% </template>
|
2025-10-20 17:32:09 +08:00
|
|
|
|
</el-table-column>
|
|
|
|
|
|
<el-table-column label="步数" prop="steps">
|
2025-10-23 17:28:06 +08:00
|
|
|
|
<template #default="scope"> {{ scope.row.steps || scope.row.walkSteps || '-' }}步</template>
|
2025-10-20 17:32:09 +08:00
|
|
|
|
</el-table-column>
|
|
|
|
|
|
<el-table-column label="设备温度" prop="temperature">
|
2025-10-23 17:28:06 +08:00
|
|
|
|
<template #default="scope"> {{ scope.row.temperature || scope.row.deviceTemp || '-' }}℃ </template>
|
|
|
|
|
|
</el-table-column>
|
|
|
|
|
|
<el-table-column label="数据最后更新时间" prop="time" width="200">
|
|
|
|
|
|
<template #default="scope"> {{ scope.row.time || scope.row.updateTime || scope.row.createTime || '-' }}</template>
|
2025-10-20 17:32:09 +08:00
|
|
|
|
</el-table-column>
|
|
|
|
|
|
<el-table-column label="操作" prop="">
|
|
|
|
|
|
<template #default="scope">
|
|
|
|
|
|
<el-button link type="primary" @click="collarlocateClick(scope.row)">定位</el-button>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</el-table-column>
|
|
|
|
|
|
</el-table>
|
|
|
|
|
|
<pagination
|
|
|
|
|
|
v-model:limit="collarLogForm.pageSize"
|
|
|
|
|
|
v-model:page="collarLogForm.pageNum"
|
|
|
|
|
|
:total="data.collarLogTotal"
|
|
|
|
|
|
@pagination="getCollarLogList"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</el-dialog>
|
2025-10-24 17:32:42 +08:00
|
|
|
|
<!-- 智能主机日志 -->
|
|
|
|
|
|
<el-dialog v-model="data.hostLogDialogVisible" title="智能主机日志" style="width: 900px; padding-bottom: 20px">
|
|
|
|
|
|
<el-table :data="data.hostLogRows" border v-loading="data.logListLoading" element-loading-text="数据加载中..." style="width: 100%">
|
|
|
|
|
|
<el-table-column label="智能主机编号" prop="deviceId"></el-table-column>
|
|
|
|
|
|
<el-table-column label="设备电量" prop="deviceVoltage">
|
|
|
|
|
|
<template #default="scope"> {{ scope.row.deviceVoltage || scope.row.battery || '-' }}% </template>
|
|
|
|
|
|
</el-table-column>
|
|
|
|
|
|
<el-table-column label="步数" prop="walkSteps">
|
|
|
|
|
|
<template #default="scope"> {{ scope.row.walkSteps || scope.row.steps || '-' }}步</template>
|
|
|
|
|
|
</el-table-column>
|
|
|
|
|
|
<el-table-column label="设备温度" prop="deviceTemp">
|
|
|
|
|
|
<template #default="scope"> {{ scope.row.deviceTemp || scope.row.temperature || '-' }}℃ </template>
|
|
|
|
|
|
</el-table-column>
|
|
|
|
|
|
<el-table-column label="小时时间" prop="hourTime" width="200">
|
|
|
|
|
|
<template #default="scope"> {{ scope.row.hourTime || '-' }}</template>
|
|
|
|
|
|
</el-table-column>
|
|
|
|
|
|
<el-table-column label="数据最后更新时间" prop="updateTime" width="200">
|
|
|
|
|
|
<template #default="scope"> {{ scope.row.updateTime || scope.row.createTime || '-' }}</template>
|
|
|
|
|
|
</el-table-column>
|
|
|
|
|
|
<el-table-column label="操作" prop="">
|
|
|
|
|
|
<template #default="scope">
|
|
|
|
|
|
<el-button link type="primary" @click="hostLocationClick(scope.row)">定位</el-button>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</el-table-column>
|
|
|
|
|
|
</el-table>
|
|
|
|
|
|
</el-dialog>
|
2025-10-20 17:32:09 +08:00
|
|
|
|
|
|
|
|
|
|
<TrackDialog ref="TrackDialogRef" />
|
|
|
|
|
|
</section>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script setup>
|
2025-10-24 17:32:42 +08:00
|
|
|
|
import { ref, reactive, onMounted, computed } from 'vue';
|
2025-10-20 17:32:09 +08:00
|
|
|
|
import { useRoute } from 'vue-router';
|
|
|
|
|
|
import { ElMessage } from 'element-plus';
|
2025-10-24 17:32:42 +08:00
|
|
|
|
import { earList, hostLocation, hostTrack, waybillDetail, collarList, collarLogList, earLogList, testDeliveryDevices, pageDeviceList, getEarTagLogs, getCollarLogs, getHostLogs, getEarTagTrajectory, getCollarTrajectory, getHostTrajectory } from '@/api/abroad.js';
|
2025-10-20 17:32:09 +08:00
|
|
|
|
import startIcon from '../../assets/images/qi.png';
|
|
|
|
|
|
import endIcon from '../../assets/images/zhong.png';
|
|
|
|
|
|
import TrackDialog from '../hardware/trackDialog.vue';
|
|
|
|
|
|
|
|
|
|
|
|
const route = useRoute();
|
|
|
|
|
|
const TrackDialogRef = ref();
|
|
|
|
|
|
const startMarkIcon = reactive({
|
|
|
|
|
|
url: startIcon,
|
|
|
|
|
|
size: { width: 32, height: 32 },
|
|
|
|
|
|
opts: { anchor: { width: 16, height: 16 } },
|
|
|
|
|
|
});
|
|
|
|
|
|
const endMarkIcon = reactive({
|
|
|
|
|
|
url: endIcon,
|
|
|
|
|
|
size: { width: 32, height: 32 },
|
|
|
|
|
|
opts: { anchor: { width: 16, height: 16 } },
|
|
|
|
|
|
});
|
|
|
|
|
|
const data = reactive({
|
|
|
|
|
|
status: '',
|
|
|
|
|
|
length: '',
|
|
|
|
|
|
imgArr: [],
|
|
|
|
|
|
baseInfo: {
|
|
|
|
|
|
id: 1,
|
|
|
|
|
|
createByDesc: '申报人',
|
|
|
|
|
|
createByPhone: '联系电话',
|
|
|
|
|
|
rgstJbqNum: '申报数量',
|
|
|
|
|
|
createTime: '创建时间',
|
|
|
|
|
|
deliverNo: '申报运单号',
|
|
|
|
|
|
carNo: '车牌号',
|
|
|
|
|
|
quarStatusDesc: '入场状态', // 根据status反显
|
|
|
|
|
|
status: '订单状态 1境外预检 2 已入境待隔离(检疫成功) 3 已入隔离场 4 隔离场出场 ',
|
|
|
|
|
|
deliverTime: '启运时间',
|
|
|
|
|
|
},
|
|
|
|
|
|
warnInfo: [],
|
|
|
|
|
|
serverIds: '',
|
|
|
|
|
|
dataListLoading: false,
|
|
|
|
|
|
rows: [],
|
|
|
|
|
|
total: 0,
|
|
|
|
|
|
radio: '1',
|
|
|
|
|
|
checkStatus: '', // 车内盘点状态
|
|
|
|
|
|
hgCheckStatus: '', // 海关盘点状态
|
|
|
|
|
|
dialogVisible: false, // 查看主机弹窗
|
|
|
|
|
|
center: { lng: 0, lat: 0 },
|
|
|
|
|
|
updateTime: '', // 主机定位时间
|
|
|
|
|
|
// 轨迹
|
|
|
|
|
|
trackDialogVisible: false,
|
|
|
|
|
|
trackZoom: 15,
|
|
|
|
|
|
path: [],
|
|
|
|
|
|
centerPoint: { lng: 0, lat: 0 },
|
|
|
|
|
|
trackLoading: false,
|
|
|
|
|
|
trajectoryStatus: true,
|
|
|
|
|
|
startMark: {},
|
|
|
|
|
|
endMark: {},
|
|
|
|
|
|
confirmLoading: false,
|
|
|
|
|
|
collarDataListLoading: false,
|
|
|
|
|
|
collarRows: [],
|
|
|
|
|
|
collarTotal: 0,
|
|
|
|
|
|
logListLoading: false,
|
|
|
|
|
|
earLogRows: [],
|
|
|
|
|
|
earLogDialogVisible: false,
|
|
|
|
|
|
collarDialogVisible: false,
|
2025-10-24 17:32:42 +08:00
|
|
|
|
hostLogDialogVisible: false,
|
2025-10-20 17:32:09 +08:00
|
|
|
|
earLogTotal: 0,
|
|
|
|
|
|
collarLogRows: [],
|
|
|
|
|
|
collarLogTotal: 0,
|
2025-10-24 17:32:42 +08:00
|
|
|
|
hostLogRows: [],
|
|
|
|
|
|
hostLogTotal: 0,
|
2025-10-20 17:32:09 +08:00
|
|
|
|
deviceId: '', // 耳标编号
|
|
|
|
|
|
sn: '', // 项圈编号
|
2025-10-24 17:32:42 +08:00
|
|
|
|
// 智能主机相关
|
|
|
|
|
|
hostDataListLoading: false,
|
|
|
|
|
|
hostRows: [],
|
|
|
|
|
|
hostTotal: 0,
|
2025-10-20 17:32:09 +08:00
|
|
|
|
});
|
|
|
|
|
|
const form = reactive({
|
|
|
|
|
|
pageNum: 1,
|
|
|
|
|
|
pageSize: 10,
|
|
|
|
|
|
});
|
|
|
|
|
|
const collarForm = reactive({
|
|
|
|
|
|
pageNum: 1,
|
|
|
|
|
|
pageSize: 10,
|
|
|
|
|
|
});
|
|
|
|
|
|
// 耳标日志
|
|
|
|
|
|
const earLogForm = reactive({
|
|
|
|
|
|
pageNum: 1,
|
|
|
|
|
|
pageSize: 10,
|
|
|
|
|
|
});
|
|
|
|
|
|
// 项圈日志
|
|
|
|
|
|
const collarLogForm = reactive({
|
|
|
|
|
|
pageNum: 1,
|
|
|
|
|
|
pageSize: 10,
|
|
|
|
|
|
});
|
|
|
|
|
|
// 查详情
|
|
|
|
|
|
const getDetail = () => {
|
|
|
|
|
|
console.log('查询运单详情, deliveryId:', route.query.id);
|
|
|
|
|
|
|
|
|
|
|
|
if (!route.query.id) {
|
|
|
|
|
|
console.warn('=== 警告:deliveryId为空,跳过运单详情查询');
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
waybillDetail(route.query.id)
|
|
|
|
|
|
.then((res) => {
|
|
|
|
|
|
console.log('运单详情返回结果:', res);
|
|
|
|
|
|
if (res.code === 200) {
|
|
|
|
|
|
data.baseInfo = res.data.delivery ? res.data.delivery : {};
|
|
|
|
|
|
data.warnInfo = res.data.warningLog ? res.data.warningLog : {};
|
|
|
|
|
|
data.serverIds = res.data.serverIds ? res.data.serverIds : [];
|
|
|
|
|
|
console.log('基础信息:', {
|
|
|
|
|
|
driverName: data.baseInfo.driverName,
|
|
|
|
|
|
licensePlate: data.baseInfo.licensePlate,
|
|
|
|
|
|
carFrontPhoto: data.baseInfo.carFrontPhoto,
|
|
|
|
|
|
carBehindPhoto: data.baseInfo.carBehindPhoto,
|
|
|
|
|
|
driverId: data.baseInfo.driverId
|
|
|
|
|
|
});
|
2025-10-23 17:28:06 +08:00
|
|
|
|
|
|
|
|
|
|
// 使用新的统一API获取智能主机信息
|
|
|
|
|
|
getHostDeviceInfo();
|
2025-10-20 17:32:09 +08:00
|
|
|
|
} else {
|
|
|
|
|
|
ElMessage.error(res.msg);
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
.catch(() => {});
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2025-10-24 17:32:42 +08:00
|
|
|
|
// 智能主机列表查询
|
|
|
|
|
|
const getHostList = () => {
|
2025-10-23 17:28:06 +08:00
|
|
|
|
if (!route.query.id) {
|
2025-10-24 17:32:42 +08:00
|
|
|
|
console.warn('=== 警告:deliveryId为空,跳过主机列表查询');
|
|
|
|
|
|
data.hostDataListLoading = false;
|
2025-10-23 17:28:06 +08:00
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-24 17:32:42 +08:00
|
|
|
|
data.hostDataListLoading = true;
|
2025-10-23 17:28:06 +08:00
|
|
|
|
pageDeviceList({
|
|
|
|
|
|
pageNum: 1,
|
|
|
|
|
|
pageSize: 100, // 获取所有主机设备
|
|
|
|
|
|
deliveryId: parseInt(route.query.id),
|
|
|
|
|
|
deviceType: 1, // 智能主机设备类型
|
|
|
|
|
|
})
|
|
|
|
|
|
.then((res) => {
|
|
|
|
|
|
console.log('=== 主机设备API返回结果:', res);
|
2025-10-24 17:32:42 +08:00
|
|
|
|
data.hostDataListLoading = false;
|
2025-10-23 17:28:06 +08:00
|
|
|
|
if (res.code === 200) {
|
|
|
|
|
|
console.log('=== 主机设备数据:', res.data);
|
|
|
|
|
|
// 新API返回的是数组格式,过滤出智能主机设备
|
|
|
|
|
|
const hostDevices = res.data.filter(device => device.deviceType === 1 || device.deviceType === '1');
|
2025-10-24 17:32:42 +08:00
|
|
|
|
data.hostRows = hostDevices || [];
|
|
|
|
|
|
data.hostTotal = hostDevices.length || 0;
|
|
|
|
|
|
|
2025-10-23 17:28:06 +08:00
|
|
|
|
if (hostDevices.length > 0) {
|
|
|
|
|
|
// 如果有主机设备,取第一个作为主要主机
|
|
|
|
|
|
data.serverIds = hostDevices[0].deviceId || hostDevices[0].sn || '';
|
|
|
|
|
|
console.log('=== 设置后的serverIds:', data.serverIds);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
data.serverIds = '';
|
|
|
|
|
|
}
|
2025-10-24 17:32:42 +08:00
|
|
|
|
|
|
|
|
|
|
console.log('=== 设置后的hostRows:', data.hostRows);
|
|
|
|
|
|
console.log('=== 设置后的hostTotal:', data.hostTotal);
|
2025-10-23 17:28:06 +08:00
|
|
|
|
} else {
|
|
|
|
|
|
console.warn('获取主机设备信息失败:', res.msg);
|
2025-10-24 17:32:42 +08:00
|
|
|
|
data.hostRows = [];
|
|
|
|
|
|
data.hostTotal = 0;
|
2025-10-23 17:28:06 +08:00
|
|
|
|
data.serverIds = '';
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
.catch((err) => {
|
|
|
|
|
|
console.error('获取主机设备信息异常:', err);
|
2025-10-24 17:32:42 +08:00
|
|
|
|
data.hostDataListLoading = false;
|
|
|
|
|
|
data.hostRows = [];
|
|
|
|
|
|
data.hostTotal = 0;
|
2025-10-23 17:28:06 +08:00
|
|
|
|
data.serverIds = '';
|
|
|
|
|
|
});
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2025-10-24 17:32:42 +08:00
|
|
|
|
// 获取智能主机信息(保留原有功能)
|
|
|
|
|
|
const getHostDeviceInfo = () => {
|
|
|
|
|
|
// 现在直接调用getHostList来获取主机信息
|
|
|
|
|
|
getHostList();
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2025-10-20 17:32:09 +08:00
|
|
|
|
// 查看主机定位
|
|
|
|
|
|
const locationClick = (item) => {
|
|
|
|
|
|
getHostLocation(item);
|
|
|
|
|
|
};
|
|
|
|
|
|
//
|
|
|
|
|
|
// 查询主机经纬度
|
|
|
|
|
|
const getHostLocation = (item) => {
|
|
|
|
|
|
hostLocation({
|
|
|
|
|
|
serverDeviceId: data.serverIds,
|
|
|
|
|
|
})
|
|
|
|
|
|
.then((res) => {
|
|
|
|
|
|
if (res.code === 200) {
|
|
|
|
|
|
data.center.lng = res.data.longitude;
|
|
|
|
|
|
data.center.lat = res.data.latitude;
|
|
|
|
|
|
data.updateTime = res.data.updateTime;
|
|
|
|
|
|
data.dialogVisible = true;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
ElMessage.error(res.msg);
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
.catch(() => {});
|
|
|
|
|
|
};
|
|
|
|
|
|
// 查看运动轨迹
|
|
|
|
|
|
const trackClick = (item) => {
|
|
|
|
|
|
data.trackDialogVisible = true;
|
|
|
|
|
|
getHostTrack(item);
|
|
|
|
|
|
};
|
|
|
|
|
|
// 查询主机运动轨迹
|
|
|
|
|
|
const getHostTrack = (item) => {
|
|
|
|
|
|
data.trackLoading = true;
|
|
|
|
|
|
hostTrack({
|
|
|
|
|
|
deliveryId: data.baseInfo.id,
|
|
|
|
|
|
serverDeviceId: Number(item),
|
|
|
|
|
|
})
|
|
|
|
|
|
.then((res) => {
|
|
|
|
|
|
data.trackLoading = false;
|
|
|
|
|
|
if (res.code === 200) {
|
|
|
|
|
|
if (res.data.length > 0) {
|
|
|
|
|
|
data.trajectoryStatus = false;
|
|
|
|
|
|
data.path = [];
|
|
|
|
|
|
res.data.forEach((item, index) => {
|
|
|
|
|
|
data.path.unshift({
|
|
|
|
|
|
lng: item.longitude,
|
|
|
|
|
|
lat: item.latitude,
|
|
|
|
|
|
});
|
|
|
|
|
|
});
|
|
|
|
|
|
data.startMark = data.path[0]; // 起点
|
|
|
|
|
|
data.endMark = data.path[data.path.length - 1]; // 终点
|
|
|
|
|
|
} else {
|
|
|
|
|
|
data.trajectoryStatus = true;
|
|
|
|
|
|
data.path = [];
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
ElMessage.error(res.msg);
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
.catch(() => {
|
|
|
|
|
|
data.trackLoading = false;
|
|
|
|
|
|
data.trajectoryStatus = true;
|
|
|
|
|
|
});
|
|
|
|
|
|
};
|
|
|
|
|
|
// --------- 智能耳标 -----------
|
|
|
|
|
|
// 耳标列表查询
|
|
|
|
|
|
const getEarList = () => {
|
|
|
|
|
|
if (!route.query.id) {
|
|
|
|
|
|
console.warn('=== 警告:deliveryId为空,跳过耳标列表查询');
|
|
|
|
|
|
data.dataListLoading = false;
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
data.dataListLoading = true;
|
2025-10-23 17:28:06 +08:00
|
|
|
|
pageDeviceList({
|
2025-10-20 17:32:09 +08:00
|
|
|
|
pageNum: form.pageNum,
|
|
|
|
|
|
pageSize: form.pageSize,
|
2025-10-23 17:28:06 +08:00
|
|
|
|
deliveryId: parseInt(route.query.id),
|
|
|
|
|
|
deviceType: 2, // 智能耳标设备类型
|
2025-10-20 17:32:09 +08:00
|
|
|
|
})
|
|
|
|
|
|
.then((res) => {
|
|
|
|
|
|
console.log('=== 耳标设备API返回结果:', res);
|
|
|
|
|
|
data.dataListLoading = false;
|
|
|
|
|
|
if (res.code === 200) {
|
|
|
|
|
|
console.log('=== 耳标设备数据:', res.data);
|
2025-10-23 17:28:06 +08:00
|
|
|
|
// 新API返回的是数组格式,需要过滤出智能耳标设备
|
|
|
|
|
|
const earDevices = res.data.filter(device => device.deviceType === 2 || device.deviceType === '2');
|
|
|
|
|
|
data.rows = earDevices || [];
|
|
|
|
|
|
data.total = earDevices.length || 0;
|
2025-10-20 17:32:09 +08:00
|
|
|
|
console.log('=== 设置后的rows:', data.rows);
|
|
|
|
|
|
console.log('=== 设置后的total:', data.total);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
ElMessage.error(res.msg);
|
|
|
|
|
|
data.total = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
.catch(() => {
|
|
|
|
|
|
data.dataListLoading = false;
|
|
|
|
|
|
});
|
|
|
|
|
|
};
|
|
|
|
|
|
const earLogClick = (row) => {
|
2025-10-24 17:32:42 +08:00
|
|
|
|
console.log('=== 智能耳标日志点击 ===');
|
|
|
|
|
|
console.log('设备信息:', row);
|
|
|
|
|
|
|
2025-10-23 17:28:06 +08:00
|
|
|
|
data.deviceId = row.deviceId || row.sn || '';
|
2025-10-20 17:32:09 +08:00
|
|
|
|
data.earLogDialogVisible = true;
|
2025-10-24 17:32:42 +08:00
|
|
|
|
|
|
|
|
|
|
// 调用新的API获取60分钟间隔的日志数据
|
|
|
|
|
|
getEarTagLogs({
|
|
|
|
|
|
deviceId: data.deviceId,
|
|
|
|
|
|
deliveryId: parseInt(route.query.id)
|
|
|
|
|
|
}).then((res) => {
|
|
|
|
|
|
console.log('=== 智能耳标日志API返回结果:', res);
|
|
|
|
|
|
if (res.code === 200) {
|
|
|
|
|
|
// 新API返回的是按60分钟分组的日志数据
|
|
|
|
|
|
data.earLogRows = res.data || [];
|
|
|
|
|
|
data.earLogTotal = res.data.length || 0;
|
|
|
|
|
|
console.log('=== 设置后的earLogRows:', data.earLogRows);
|
|
|
|
|
|
console.log('=== 设置后的earLogTotal:', data.earLogTotal);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
ElMessage.error(res.msg || '获取智能耳标日志失败');
|
|
|
|
|
|
data.earLogRows = [];
|
|
|
|
|
|
data.earLogTotal = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
}).catch((error) => {
|
|
|
|
|
|
console.error('获取智能耳标日志异常:', error);
|
|
|
|
|
|
ElMessage.error('获取智能耳标日志失败');
|
|
|
|
|
|
data.earLogRows = [];
|
|
|
|
|
|
data.earLogTotal = 0;
|
|
|
|
|
|
});
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 智能耳标运动轨迹
|
|
|
|
|
|
const earTrackClick = (row) => {
|
|
|
|
|
|
console.log('=== 智能耳标运动轨迹点击 ===');
|
|
|
|
|
|
console.log('设备信息:', row);
|
|
|
|
|
|
|
|
|
|
|
|
// 调用新的API获取60分钟间隔的轨迹数据
|
|
|
|
|
|
getEarTagTrajectory({
|
|
|
|
|
|
deviceId: row.deviceId || row.sn || '',
|
|
|
|
|
|
deliveryId: parseInt(route.query.id)
|
|
|
|
|
|
}).then((res) => {
|
|
|
|
|
|
console.log('=== 智能耳标轨迹API返回结果:', res);
|
|
|
|
|
|
if (res.code === 200 && res.data && res.data.length > 0) {
|
|
|
|
|
|
// 新API返回的是按60分钟分组的轨迹点数据
|
|
|
|
|
|
const trajectoryPoints = res.data;
|
|
|
|
|
|
console.log('=== 轨迹点数据:', trajectoryPoints);
|
|
|
|
|
|
|
|
|
|
|
|
// 使用TrackDialog显示轨迹
|
|
|
|
|
|
if (TrackDialogRef.value) {
|
|
|
|
|
|
const info = {
|
|
|
|
|
|
deliveryId: route.query.id,
|
|
|
|
|
|
deviceId: row.deviceId || row.sn || '',
|
|
|
|
|
|
type: 'order',
|
|
|
|
|
|
trajectoryPoints: trajectoryPoints // 传递轨迹点数据
|
|
|
|
|
|
};
|
|
|
|
|
|
TrackDialogRef.value.onShowTrackDialog(info);
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
ElMessage.warning('该设备暂无运动轨迹数据');
|
|
|
|
|
|
}
|
|
|
|
|
|
}).catch((error) => {
|
|
|
|
|
|
console.error('获取智能耳标轨迹异常:', error);
|
|
|
|
|
|
ElMessage.error('获取智能耳标运动轨迹失败');
|
|
|
|
|
|
});
|
2025-10-20 17:32:09 +08:00
|
|
|
|
};
|
2025-10-24 17:32:42 +08:00
|
|
|
|
|
2025-10-20 17:32:09 +08:00
|
|
|
|
// 智能项圈列表查询
|
|
|
|
|
|
const getCollarList = () => {
|
|
|
|
|
|
if (!route.query.id) {
|
|
|
|
|
|
console.warn('=== 警告:deliveryId为空,跳过项圈列表查询');
|
|
|
|
|
|
data.collarDataListLoading = false;
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
data.collarDataListLoading = true;
|
2025-10-23 17:28:06 +08:00
|
|
|
|
pageDeviceList({
|
2025-10-20 17:32:09 +08:00
|
|
|
|
pageNum: collarForm.pageNum,
|
|
|
|
|
|
pageSize: collarForm.pageSize,
|
2025-10-23 17:28:06 +08:00
|
|
|
|
deliveryId: parseInt(route.query.id),
|
|
|
|
|
|
deviceType: 4, // 智能项圈设备类型
|
2025-10-20 17:32:09 +08:00
|
|
|
|
})
|
|
|
|
|
|
.then((res) => {
|
|
|
|
|
|
console.log('=== 项圈设备API返回结果:', res);
|
|
|
|
|
|
data.collarDataListLoading = false;
|
|
|
|
|
|
if (res.code === 200) {
|
|
|
|
|
|
console.log('=== 项圈设备数据:', res.data);
|
2025-10-23 17:28:06 +08:00
|
|
|
|
// 新API返回的是数组格式,需要过滤出智能项圈设备
|
|
|
|
|
|
const collarDevices = res.data.filter(device => device.deviceType === 4 || device.deviceType === '4');
|
|
|
|
|
|
data.collarRows = collarDevices || [];
|
|
|
|
|
|
data.collarTotal = collarDevices.length || 0;
|
2025-10-20 17:32:09 +08:00
|
|
|
|
console.log('=== 设置后的collarRows:', data.collarRows);
|
|
|
|
|
|
console.log('=== 设置后的collarTotal:', data.collarTotal);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
ElMessage.error(res.msg);
|
|
|
|
|
|
data.collarTotal = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
.catch(() => {
|
|
|
|
|
|
data.collarDataListLoading = false;
|
|
|
|
|
|
data.collarTotal = 0; // 确保total有默认值
|
|
|
|
|
|
});
|
|
|
|
|
|
};
|
|
|
|
|
|
const collarLogClick = (row) => {
|
2025-10-24 17:32:42 +08:00
|
|
|
|
console.log('=== 智能项圈日志点击 ===');
|
|
|
|
|
|
console.log('设备信息:', row);
|
|
|
|
|
|
|
2025-10-23 17:28:06 +08:00
|
|
|
|
data.sn = row.sn || row.deviceId || '';
|
2025-10-20 17:32:09 +08:00
|
|
|
|
data.collarDialogVisible = true;
|
2025-10-24 17:32:42 +08:00
|
|
|
|
|
|
|
|
|
|
// 调用新的API获取60分钟间隔的日志数据
|
|
|
|
|
|
getCollarLogs({
|
|
|
|
|
|
deviceId: data.sn,
|
|
|
|
|
|
deliveryId: parseInt(route.query.id)
|
|
|
|
|
|
}).then((res) => {
|
|
|
|
|
|
console.log('=== 智能项圈日志API返回结果:', res);
|
|
|
|
|
|
if (res.code === 200) {
|
|
|
|
|
|
// 新API返回的是按60分钟分组的日志数据
|
|
|
|
|
|
data.collarLogRows = res.data || [];
|
|
|
|
|
|
data.collarLogTotal = res.data.length || 0;
|
|
|
|
|
|
console.log('=== 设置后的collarLogRows:', data.collarLogRows);
|
|
|
|
|
|
console.log('=== 设置后的collarLogTotal:', data.collarLogTotal);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
ElMessage.error(res.msg || '获取智能项圈日志失败');
|
|
|
|
|
|
data.collarLogRows = [];
|
|
|
|
|
|
data.collarLogTotal = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
}).catch((error) => {
|
|
|
|
|
|
console.error('获取智能项圈日志异常:', error);
|
|
|
|
|
|
ElMessage.error('获取智能项圈日志失败');
|
|
|
|
|
|
data.collarLogRows = [];
|
|
|
|
|
|
data.collarLogTotal = 0;
|
|
|
|
|
|
});
|
2025-10-20 17:32:09 +08:00
|
|
|
|
};
|
|
|
|
|
|
const handler = ({ BMap, map }) => {
|
|
|
|
|
|
// 自动获取展示的比例
|
|
|
|
|
|
const view = map.getViewport(eval(data.path));
|
|
|
|
|
|
data.trackZoom = view.zoom;
|
|
|
|
|
|
data.centerPoint = view.center;
|
|
|
|
|
|
};
|
|
|
|
|
|
// 取消按钮
|
|
|
|
|
|
const cancelClick = () => {
|
|
|
|
|
|
window.history.go(-1);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 返回上一页
|
|
|
|
|
|
const goBack = () => {
|
|
|
|
|
|
window.history.go(-1);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 前往列表页面
|
|
|
|
|
|
const goToList = () => {
|
|
|
|
|
|
router.push('/entry/attestation');
|
|
|
|
|
|
};
|
|
|
|
|
|
// 弹层
|
|
|
|
|
|
const locateClick = (row) => {
|
|
|
|
|
|
data.center.lng = row.longitude;
|
|
|
|
|
|
data.center.lat = row.latitude;
|
2025-10-23 17:28:06 +08:00
|
|
|
|
data.updateTime = row.updateTime || row.createTime || '';
|
2025-10-20 17:32:09 +08:00
|
|
|
|
data.dialogVisible = true;
|
|
|
|
|
|
};
|
|
|
|
|
|
//
|
|
|
|
|
|
const collarlocateClick = (row) => {
|
|
|
|
|
|
data.center.lng = row.longitude;
|
|
|
|
|
|
data.center.lat = row.latitude;
|
2025-10-23 17:28:06 +08:00
|
|
|
|
data.updateTime = row.time || row.updateTime || row.createTime || '';
|
2025-10-20 17:32:09 +08:00
|
|
|
|
data.dialogVisible = true;
|
|
|
|
|
|
};
|
|
|
|
|
|
// 耳标日志列表
|
|
|
|
|
|
const getEarLogList = () => {
|
|
|
|
|
|
data.logListLoading = true;
|
|
|
|
|
|
earLogList({
|
|
|
|
|
|
pageNum: earLogForm.pageNum,
|
|
|
|
|
|
pageSize: earLogForm.pageSize,
|
|
|
|
|
|
deliveryId: route.query.id,
|
|
|
|
|
|
deviceId: data.deviceId,
|
|
|
|
|
|
})
|
|
|
|
|
|
.then((res) => {
|
|
|
|
|
|
data.logListLoading = false;
|
|
|
|
|
|
if (res.code === 200) {
|
|
|
|
|
|
data.earLogRows = res.data.rows;
|
|
|
|
|
|
data.earLogTotal = res.data.total;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
ElMessage.error(res.msg);
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
.catch(() => {
|
|
|
|
|
|
data.logListLoading = false;
|
|
|
|
|
|
data.earLogTotal = 0; // 确保total有默认值
|
|
|
|
|
|
});
|
|
|
|
|
|
};
|
|
|
|
|
|
// 项圈日志列表
|
|
|
|
|
|
const getCollarLogList = () => {
|
|
|
|
|
|
data.logListLoading = true;
|
|
|
|
|
|
collarLogList({
|
|
|
|
|
|
pageNum: collarLogForm.pageNum,
|
|
|
|
|
|
pageSize: collarLogForm.pageSize,
|
|
|
|
|
|
deliveryId: route.query.id,
|
|
|
|
|
|
deviceId: data.sn,
|
|
|
|
|
|
})
|
|
|
|
|
|
.then((res) => {
|
|
|
|
|
|
data.logListLoading = false;
|
|
|
|
|
|
if (res.code === 200) {
|
|
|
|
|
|
data.collarLogRows = res.data.rows;
|
|
|
|
|
|
data.collarLogTotal = res.data.total;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
ElMessage.error(res.msg);
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
.catch(() => {
|
|
|
|
|
|
data.logListLoading = false;
|
|
|
|
|
|
data.collarLogTotal = 0; // 确保total有默认值
|
|
|
|
|
|
});
|
|
|
|
|
|
};
|
|
|
|
|
|
// 查看运动轨迹
|
|
|
|
|
|
const collarTrackClick = (row) => {
|
2025-10-24 17:32:42 +08:00
|
|
|
|
console.log('=== 智能项圈运动轨迹点击 ===');
|
|
|
|
|
|
console.log('设备信息:', row);
|
|
|
|
|
|
|
|
|
|
|
|
// 调用新的API获取60分钟间隔的轨迹数据
|
|
|
|
|
|
getCollarTrajectory({
|
|
|
|
|
|
deviceId: row.sn || row.deviceId || '',
|
|
|
|
|
|
deliveryId: parseInt(route.query.id)
|
|
|
|
|
|
}).then((res) => {
|
|
|
|
|
|
console.log('=== 智能项圈轨迹API返回结果:', res);
|
|
|
|
|
|
if (res.code === 200 && res.data && res.data.length > 0) {
|
|
|
|
|
|
// 新API返回的是按60分钟分组的轨迹点数据
|
|
|
|
|
|
const trajectoryPoints = res.data;
|
|
|
|
|
|
console.log('=== 轨迹点数据:', trajectoryPoints);
|
|
|
|
|
|
|
|
|
|
|
|
// 使用TrackDialog显示轨迹
|
|
|
|
|
|
if (TrackDialogRef.value) {
|
|
|
|
|
|
const info = {
|
|
|
|
|
|
deliveryId: route.query.id,
|
|
|
|
|
|
deviceId: row.sn || row.deviceId || '',
|
|
|
|
|
|
type: 'order',
|
|
|
|
|
|
trajectoryPoints: trajectoryPoints // 传递轨迹点数据
|
|
|
|
|
|
};
|
|
|
|
|
|
TrackDialogRef.value.onShowTrackDialog(info);
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
ElMessage.warning('该设备暂无运动轨迹数据');
|
|
|
|
|
|
}
|
|
|
|
|
|
}).catch((error) => {
|
|
|
|
|
|
console.error('获取智能项圈轨迹异常:', error);
|
|
|
|
|
|
ElMessage.error('获取智能项圈运动轨迹失败');
|
|
|
|
|
|
});
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 智能主机操作函数
|
|
|
|
|
|
const hostLogClick = (row) => {
|
|
|
|
|
|
console.log('=== 智能主机日志点击 ===');
|
|
|
|
|
|
console.log('设备信息:', row);
|
|
|
|
|
|
|
|
|
|
|
|
data.deviceId = row.deviceId || row.sn || '';
|
|
|
|
|
|
data.hostLogDialogVisible = true;
|
|
|
|
|
|
|
|
|
|
|
|
// 调用新的API获取60分钟间隔的日志数据
|
|
|
|
|
|
getHostLogs({
|
|
|
|
|
|
deviceId: data.deviceId,
|
|
|
|
|
|
deliveryId: parseInt(route.query.id)
|
|
|
|
|
|
}).then((res) => {
|
|
|
|
|
|
console.log('=== 智能主机日志API返回结果:', res);
|
|
|
|
|
|
if (res.code === 200) {
|
|
|
|
|
|
// 新API返回的是按60分钟分组的日志数据
|
|
|
|
|
|
data.hostLogRows = res.data || [];
|
|
|
|
|
|
data.hostLogTotal = res.data.length || 0;
|
|
|
|
|
|
console.log('=== 设置后的hostLogRows:', data.hostLogRows);
|
|
|
|
|
|
console.log('=== 设置后的hostLogTotal:', data.hostLogTotal);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
ElMessage.error(res.msg || '获取智能主机日志失败');
|
|
|
|
|
|
data.hostLogRows = [];
|
|
|
|
|
|
data.hostLogTotal = 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
}).catch((error) => {
|
|
|
|
|
|
console.error('获取智能主机日志异常:', error);
|
|
|
|
|
|
ElMessage.error('获取智能主机日志失败');
|
|
|
|
|
|
data.hostLogRows = [];
|
|
|
|
|
|
data.hostLogTotal = 0;
|
|
|
|
|
|
});
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const hostTrackClick = (row) => {
|
|
|
|
|
|
console.log('=== 智能主机运动轨迹点击 ===');
|
|
|
|
|
|
console.log('设备信息:', row);
|
|
|
|
|
|
|
|
|
|
|
|
// 调用新的API获取60分钟间隔的轨迹数据
|
|
|
|
|
|
getHostTrajectory({
|
|
|
|
|
|
deviceId: row.deviceId || row.sn || '',
|
|
|
|
|
|
deliveryId: parseInt(route.query.id)
|
|
|
|
|
|
}).then((res) => {
|
|
|
|
|
|
console.log('=== 智能主机轨迹API返回结果:', res);
|
|
|
|
|
|
if (res.code === 200 && res.data && res.data.length > 0) {
|
|
|
|
|
|
// 新API返回的是按60分钟分组的轨迹点数据
|
|
|
|
|
|
const trajectoryPoints = res.data;
|
|
|
|
|
|
console.log('=== 轨迹点数据:', trajectoryPoints);
|
|
|
|
|
|
|
|
|
|
|
|
// 使用TrackDialog显示轨迹
|
|
|
|
|
|
if (TrackDialogRef.value) {
|
|
|
|
|
|
const info = {
|
|
|
|
|
|
deliveryId: route.query.id,
|
|
|
|
|
|
deviceId: row.deviceId || row.sn || '',
|
|
|
|
|
|
type: 'order',
|
|
|
|
|
|
trajectoryPoints: trajectoryPoints // 传递轨迹点数据
|
|
|
|
|
|
};
|
|
|
|
|
|
TrackDialogRef.value.onShowTrackDialog(info);
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
ElMessage.warning('该设备暂无运动轨迹数据');
|
|
|
|
|
|
}
|
|
|
|
|
|
}).catch((error) => {
|
|
|
|
|
|
console.error('获取智能主机轨迹异常:', error);
|
|
|
|
|
|
ElMessage.error('获取智能主机运动轨迹失败');
|
|
|
|
|
|
});
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const hostLocationClick = (row) => {
|
|
|
|
|
|
data.center.lng = row.longitude;
|
|
|
|
|
|
data.center.lat = row.latitude;
|
|
|
|
|
|
data.updateTime = row.updateTime || row.createTime || '';
|
|
|
|
|
|
data.dialogVisible = true;
|
2025-10-20 17:32:09 +08:00
|
|
|
|
};
|
|
|
|
|
|
// 状态文本转换
|
2025-10-24 17:32:42 +08:00
|
|
|
|
// 计算所有绑定设备的总数
|
|
|
|
|
|
const totalRegisteredDevices = computed(() => {
|
|
|
|
|
|
const hostCount = data.hostTotal || 0;
|
|
|
|
|
|
const earCount = data.total || 0;
|
|
|
|
|
|
const collarCount = data.collarTotal || 0;
|
|
|
|
|
|
const total = hostCount + earCount + collarCount;
|
|
|
|
|
|
console.log('=== 计算设备总数 - 主机:', hostCount, '耳标:', earCount, '项圈:', collarCount, '总计:', total);
|
|
|
|
|
|
return total;
|
|
|
|
|
|
});
|
|
|
|
|
|
|
2025-10-20 17:32:09 +08:00
|
|
|
|
const getStatusText = (status) => {
|
|
|
|
|
|
const statusMap = {
|
|
|
|
|
|
1: '待装车',
|
2025-10-27 17:38:20 +08:00
|
|
|
|
2: '已装车/预付款已支付',
|
|
|
|
|
|
3: '已装车/尾款待支付',
|
|
|
|
|
|
4: '已核验/待买家付款',
|
|
|
|
|
|
5: '尾款已付款',
|
|
|
|
|
|
6: '发票待开/进项票',
|
|
|
|
|
|
7: '发票待开/销项'
|
2025-10-20 17:32:09 +08:00
|
|
|
|
};
|
|
|
|
|
|
return statusMap[status] || '未知状态';
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2025-10-27 17:38:20 +08:00
|
|
|
|
// 根据状态返回标签类型(颜色)
|
|
|
|
|
|
const getStatusType = (status) => {
|
|
|
|
|
|
const typeMap = {
|
|
|
|
|
|
1: 'info', // 待装车 - 灰色
|
|
|
|
|
|
2: 'success', // 已装车/预付款已支付 - 绿色
|
|
|
|
|
|
3: 'warning', // 已装车/尾款待支付 - 橙色
|
|
|
|
|
|
4: 'warning', // 已核验/待买家付款 - 橙色
|
|
|
|
|
|
5: 'success', // 尾款已付款 - 绿色
|
|
|
|
|
|
6: 'primary', // 发票待开/进项票 - 蓝色
|
|
|
|
|
|
7: 'primary' // 发票待开/销项 - 蓝色
|
|
|
|
|
|
};
|
|
|
|
|
|
return typeMap[status] || 'info';
|
|
|
|
|
|
};
|
|
|
|
|
|
|
2025-10-20 17:32:09 +08:00
|
|
|
|
onMounted(() => {
|
|
|
|
|
|
data.id = route.query.id;
|
|
|
|
|
|
data.status = route.query.status;
|
|
|
|
|
|
data.length = route.query.length;
|
|
|
|
|
|
|
|
|
|
|
|
console.log('=== 详情页面初始化,deliveryId:', route.query.id);
|
|
|
|
|
|
console.log('=== 路由参数:', route.query);
|
|
|
|
|
|
|
|
|
|
|
|
// 检查deliveryId是否存在
|
|
|
|
|
|
if (!route.query.id) {
|
|
|
|
|
|
console.warn('=== 警告:deliveryId为空,无法加载详情页面');
|
|
|
|
|
|
ElMessage.error('缺少必要的参数,请从列表页面点击详情按钮进入');
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 检查deliveryId是否存在,存在时才测试设备关联情况
|
|
|
|
|
|
testDeliveryDevices({ deliveryId: route.query.id })
|
|
|
|
|
|
.then(res => {
|
|
|
|
|
|
console.log('=== 测试设备关联结果:', res);
|
|
|
|
|
|
})
|
|
|
|
|
|
.catch(err => {
|
|
|
|
|
|
console.error('=== 测试设备关联失败:', err);
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
getDetail(); // 查详情
|
2025-10-24 17:32:42 +08:00
|
|
|
|
getHostList(); // 主机列表查询
|
2025-10-20 17:32:09 +08:00
|
|
|
|
getEarList(); // 耳标列表查询
|
|
|
|
|
|
getCollarList(); // 项圈类别查询
|
|
|
|
|
|
});
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<style lang="less" scoped>
|
|
|
|
|
|
.error-container {
|
|
|
|
|
|
padding: 50px;
|
|
|
|
|
|
text-align: center;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.info-box {
|
|
|
|
|
|
margin-top: 10px;
|
|
|
|
|
|
}
|
|
|
|
|
|
.title {
|
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
|
margin-bottom: 10px;
|
|
|
|
|
|
}
|
|
|
|
|
|
.quarantine-text {
|
|
|
|
|
|
margin-top: 20px;
|
|
|
|
|
|
}
|
|
|
|
|
|
:deep(.my-label) {
|
|
|
|
|
|
display: inline-block;
|
|
|
|
|
|
width: 120px;
|
|
|
|
|
|
text-align: right;
|
|
|
|
|
|
word-break: break-all;
|
|
|
|
|
|
}
|
|
|
|
|
|
.label {
|
|
|
|
|
|
width: 140px;
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
}
|
|
|
|
|
|
.btn-box {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
}
|
|
|
|
|
|
::v-deep .anchorBL {
|
|
|
|
|
|
display: none;
|
|
|
|
|
|
visibility: hidden;
|
|
|
|
|
|
}
|
|
|
|
|
|
.img-box {
|
|
|
|
|
|
margin-bottom: 10px;
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
.img-label {
|
|
|
|
|
|
width: 120px;
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
margin-right: 16px;
|
|
|
|
|
|
text-align: right;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
.empty-box {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
justify-content: center;
|
|
|
|
|
|
align-items: center;
|
|
|
|
|
|
}
|
|
|
|
|
|
.red {
|
|
|
|
|
|
color: #ff6332;
|
|
|
|
|
|
}
|
|
|
|
|
|
</style>
|