170 lines
5.5 KiB
Vue
170 lines
5.5 KiB
Vue
<template>
|
||
<div class="wrapper">
|
||
<el-form :inline="true" class="search-wrap" :model="form" ref="formRef">
|
||
<div>
|
||
<el-form-item style="width: 280px" prop="sn" label="项圈编号:">
|
||
<el-input placeholder="请输入项圈编号" clearable v-model="form.sn"></el-input>
|
||
</el-form-item>
|
||
<el-form-item class="inline-form-item" prop="startNo" label="号段范围:">
|
||
<el-input placeholder="请输入开始号段" v-model="form.startNo" clearable style="width: 160px" />
|
||
-
|
||
<el-input placeholder="请输入结束号段" v-model="form.endNo" style="width: 160px" clearable />
|
||
</el-form-item>
|
||
</div>
|
||
<div style="min-width: 200px">
|
||
<el-form-item>
|
||
<el-button @click="resetClick(formRef)">重置</el-button>
|
||
<el-button type="primary" @click="searchClick">查询</el-button>
|
||
</el-form-item>
|
||
</div>
|
||
</el-form>
|
||
|
||
<div class="main-container" style="margin-top: 10px">
|
||
<el-table :data="form.tableData" style="width: 100%" border>
|
||
<el-table-column label="项圈编号" prop="deviceId" />
|
||
<el-table-column label="设备电量" prop="battery">
|
||
<template #default="scope"> {{ calculateBatteryPercentage(scope.row.battery) }}% </template>
|
||
</el-table-column>
|
||
<el-table-column label="设备温度" prop="temperature">
|
||
<template #default="scope"> {{ scope.row.temperature }}°C</template>
|
||
</el-table-column>
|
||
<el-table-column prop="deliveryNumber" label="运单号" />
|
||
<el-table-column prop="carNumber" label="车牌号" />
|
||
<el-table-column prop="uptime" label="更新时间" />
|
||
<el-table-column label="操作" width="180">
|
||
<template #default="scope">
|
||
<el-button link type="primary" @click="showLocationDialog(scope.row)">定位</el-button>
|
||
<el-button link type="primary" @click="showTrackDialog(scope.row)">运动轨迹</el-button>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
<pagination v-model:limit="form.pageSize" v-model:page="form.pageNum" :total="form.total" @pagination="getList" />
|
||
<LocationDialog ref="LocationDialogRef" />
|
||
<TrackDialog ref="TrackDialogRef" />
|
||
</div>
|
||
</div>
|
||
</template>
|
||
<script setup>
|
||
import { onMounted, reactive, ref } from 'vue';
|
||
import { iotDeviceQueryList } from '~/api/hardware.js';
|
||
import LocationDialog from './locationDialog.vue';
|
||
import TrackDialog from './trackDialog.vue';
|
||
|
||
const LocationDialogRef = ref();
|
||
const TrackDialogRef = ref();
|
||
const formRef = ref();
|
||
const form = reactive({
|
||
tableData: [],
|
||
pageSize: 10,
|
||
pageNum: 1,
|
||
total: 0,
|
||
sn: '',
|
||
startNo: '',
|
||
endNo: '',
|
||
});
|
||
|
||
// 计算电量百分比:3V为100%,2.4V为0%
|
||
const calculateBatteryPercentage = (voltage) => {
|
||
if (!voltage || voltage === '' || voltage === '0') {
|
||
return 0;
|
||
}
|
||
|
||
const voltageValue = parseFloat(voltage);
|
||
if (isNaN(voltageValue)) {
|
||
return 0;
|
||
}
|
||
|
||
// 线性插值计算:3V = 100%, 2.4V = 0%
|
||
const minVoltage = 2.4;
|
||
const maxVoltage = 3.0;
|
||
|
||
if (voltageValue >= maxVoltage) {
|
||
return 100;
|
||
} else if (voltageValue <= minVoltage) {
|
||
return 0;
|
||
} else {
|
||
const percentage = ((voltageValue - minVoltage) / (maxVoltage - minVoltage)) * 100;
|
||
return Math.round(percentage);
|
||
}
|
||
};
|
||
|
||
const getList = async () => {
|
||
const { pageSize, pageNum, sn, startNo, endNo } = form;
|
||
const params = {
|
||
pageSize,
|
||
pageNum,
|
||
sn,
|
||
startNo,
|
||
endNo,
|
||
type: 4, // 项圈设备类型
|
||
};
|
||
|
||
try {
|
||
const res = await iotDeviceQueryList(params);
|
||
const { data = {}, code } = res;
|
||
|
||
if (code === 200) {
|
||
// 使用后端返回的分页数据
|
||
form.tableData = data.rows || [];
|
||
form.total = data.total || 0;
|
||
} else {
|
||
console.error('API调用失败:', res.msg);
|
||
form.tableData = [];
|
||
form.total = 0;
|
||
}
|
||
} catch (error) {
|
||
console.error('API调用异常:', error);
|
||
form.tableData = [];
|
||
form.total = 0;
|
||
}
|
||
};
|
||
const searchClick = async () => {
|
||
form.pageNum = 1;
|
||
await getList();
|
||
};
|
||
const resetClick = async (el) => {
|
||
form.pageNum = 1;
|
||
form.endNo = '';
|
||
form.startNo = '';
|
||
el.resetFields();
|
||
await getList();
|
||
};
|
||
// 查看定位
|
||
const showLocationDialog = (row) => {
|
||
if (LocationDialogRef.value) {
|
||
const normalized = {
|
||
// 兼容后端返回字段命名
|
||
deliveryId: row.deliveryId || row.delivery_id || '',
|
||
deviceId: row.deviceId || row.sn || '',
|
||
};
|
||
LocationDialogRef.value.onShowLocationDialog(normalized);
|
||
}
|
||
};
|
||
// 查看轨迹轨迹
|
||
const showTrackDialog = (row) => {
|
||
if (TrackDialogRef.value) {
|
||
TrackDialogRef.value.onShowTrackDialog(row);
|
||
}
|
||
};
|
||
onMounted(() => {
|
||
getList();
|
||
});
|
||
</script>
|
||
<style scoped lang="less">
|
||
.wrapper {
|
||
.search-wrap {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
background-color: #fff;
|
||
align-items: flex-end;
|
||
padding: 12px 16px 0 16px;
|
||
}
|
||
|
||
.btn-group {
|
||
background-color: #fff;
|
||
margin: 10px 0;
|
||
padding: 10px;
|
||
}
|
||
}
|
||
</style>
|