2025-04-02 21:02:39 +08:00
|
|
|
<template>
|
|
|
|
<div class="app-container" v-loading="loading">
|
|
|
|
<el-row :gutter="10">
|
|
|
|
<el-col :span="18">
|
|
|
|
<el-card class="card-box">
|
|
|
|
<div class="button-group">
|
|
|
|
<el-button type="primary" plain icon="el-icon-unlock" size="mini" @click="handleUnlock" v-if="canUnlock(detail)">开锁</el-button>
|
2025-04-10 14:07:21 +08:00
|
|
|
<el-button type="primary" plain icon="el-icon-lock" size="mini" @click="handleLock" v-if="canAdminLock(detail)">锁车</el-button>
|
2025-04-02 21:02:39 +08:00
|
|
|
<el-button type="primary" plain icon="el-icon-bell" size="mini" @click="handleRing">响铃</el-button>
|
|
|
|
<el-button type="primary" plain icon="el-icon-refresh" size="mini" @click="handleReboot">重启</el-button>
|
|
|
|
<el-button type="primary" plain icon="el-icon-unlock" size="mini" @click="handleUnlockSeat">开坐垫锁</el-button>
|
|
|
|
<el-button type="primary" plain icon="el-icon-refresh" size="mini" @click="handleRefresh">刷新</el-button>
|
|
|
|
<el-button type="primary" plain icon="el-icon-upload" size="mini" @click="handleOut" v-if="DeviceStatus.canOut().includes(detail.status)">出仓</el-button>
|
|
|
|
<el-button type="primary" plain icon="el-icon-download" size="mini" @click="handleIn" v-if="DeviceStatus.canIn().includes(detail.status)">入仓</el-button>
|
|
|
|
<el-button type="danger" plain icon="el-icon-close" size="mini" @click="handleDisable" v-if="DeviceStatus.canDisable().includes(detail.status)">禁用</el-button>
|
|
|
|
<el-button type="success" plain icon="el-icon-check" size="mini" @click="handleEnable" v-if="DeviceStatus.canEnable().includes(detail.status)">启用</el-button>
|
|
|
|
</div>
|
|
|
|
<collapse-panel :value="true" title="基础信息">
|
|
|
|
<el-descriptions :column="4">
|
|
|
|
<el-descriptions-item label="SN">{{ detail.sn | dv }}</el-descriptions-item>
|
|
|
|
<el-descriptions-item label="MAC">{{ detail.mac | dv }}</el-descriptions-item>
|
|
|
|
<el-descriptions-item label="车牌">{{ detail.vehicleNum | dv }}</el-descriptions-item>
|
|
|
|
<el-descriptions-item label="状态">
|
|
|
|
<dict-tag :options="dict.type.device_status" :value="detail.status" size="small"/>
|
|
|
|
</el-descriptions-item>
|
|
|
|
<el-descriptions-item label="锁状态">
|
|
|
|
<dict-tag :options="dict.type.device_lock_status" :value="detail.lockStatus" size="small"/>
|
|
|
|
</el-descriptions-item>
|
|
|
|
<el-descriptions-item label="电门">
|
|
|
|
<dict-tag :options="dict.type.device_quality" :value="detail.quality" size="small"/>
|
|
|
|
</el-descriptions-item>
|
|
|
|
<el-descriptions-item label="在线状态">
|
|
|
|
<dict-tag :options="dict.type.device_online_status" :value="detail.onlineStatus" size="small"/>
|
|
|
|
</el-descriptions-item>
|
|
|
|
<el-descriptions-item label="车辆">
|
|
|
|
<dict-tag :options="dict.type.device_iot_status" :value="detail.iotStatus" size="small"/>
|
|
|
|
</el-descriptions-item>
|
|
|
|
<el-descriptions-item label="声音">
|
|
|
|
<boolean-tag :value="detail.isSound" size="small" true-text="有声" false-text="静音"/>
|
|
|
|
</el-descriptions-item>
|
|
|
|
<el-descriptions-item label="创建时间">{{ detail.createTime | dv }}</el-descriptions-item>
|
|
|
|
<el-descriptions-item label="最后上线时间">{{ detail.lastOnlineTime | dv }}</el-descriptions-item>
|
|
|
|
</el-descriptions>
|
|
|
|
</collapse-panel>
|
|
|
|
|
|
|
|
<collapse-panel :value="true" title="位置信息">
|
|
|
|
<el-descriptions :column="4">
|
|
|
|
<el-descriptions-item label="定位">{{ detail.longitude | dv }}, {{ detail.latitude | dv }}</el-descriptions-item>
|
|
|
|
<el-descriptions-item label="最后定位时间">{{ detail.lastLocationTime | dv }}</el-descriptions-item>
|
|
|
|
<el-descriptions-item label="信号强度">{{ detail.signalStrength | dv }}</el-descriptions-item>
|
|
|
|
<el-descriptions-item label="卫星数量">{{ detail.satellites | dv }}</el-descriptions-item>
|
|
|
|
</el-descriptions>
|
|
|
|
</collapse-panel>
|
|
|
|
|
|
|
|
<collapse-panel :value="true" title="续航信息">
|
|
|
|
<el-descriptions :column="4">
|
|
|
|
<el-descriptions-item label="剩余电量">{{ detail.remainingPower | fix2 | dv }} %</el-descriptions-item>
|
|
|
|
<el-descriptions-item label="当前电压">{{ detail.voltage | fix2 | dv }} V</el-descriptions-item>
|
|
|
|
<el-descriptions-item label="剩余续航">{{ detail.remainEndurance | fix2 | dv }} KM</el-descriptions-item>
|
|
|
|
<el-descriptions-item label="满电电压">{{ detail.modelFullVoltage | fix2 | dv }} V</el-descriptions-item>
|
|
|
|
<el-descriptions-item label="亏电电压">{{ detail.modelLowVoltage | fix2 | dv }} V</el-descriptions-item>
|
|
|
|
<el-descriptions-item label="满电续航">{{ detail.modelFullEndurance | dv }} KM</el-descriptions-item>
|
|
|
|
</el-descriptions>
|
|
|
|
</collapse-panel>
|
|
|
|
</el-card>
|
|
|
|
</el-col>
|
|
|
|
|
|
|
|
<el-col :span="6">
|
|
|
|
<el-card>
|
|
|
|
<collapse-panel :value="true" title="运营信息">
|
|
|
|
<el-descriptions :column="1">
|
|
|
|
<el-descriptions-item label="运营区">{{ detail.areaName | dv }}</el-descriptions-item>
|
|
|
|
<el-descriptions-item label="运营商">{{ detail.mchName | dv }}</el-descriptions-item>
|
|
|
|
<el-descriptions-item label="车型名称">{{ detail.modelName | dv }}</el-descriptions-item>
|
|
|
|
</el-descriptions>
|
|
|
|
</collapse-panel>
|
|
|
|
|
|
|
|
<collapse-panel :value="true" title="当前订单" v-if="detail.orderNo">
|
|
|
|
<el-descriptions :column="1">
|
|
|
|
<el-descriptions-item label="订单编号">{{ detail.orderNo | dv }}</el-descriptions-item>
|
|
|
|
<el-descriptions-item label="订单状态">
|
|
|
|
<dict-tag :options="dict.type.order_status" :value="detail.orderStatus" size="small"/>
|
|
|
|
</el-descriptions-item>
|
|
|
|
<el-descriptions-item label="订单设备状态">
|
|
|
|
<dict-tag :options="dict.type.order_device_status" :value="detail.orderDeviceStatus" size="small"/>
|
|
|
|
</el-descriptions-item>
|
|
|
|
</el-descriptions>
|
|
|
|
</collapse-panel>
|
2025-04-10 14:07:21 +08:00
|
|
|
|
|
|
|
<collapse-panel :value="true" title="分成预览" v-if="detail.id && checkPermi(['bst:bonus:preview'])">
|
|
|
|
<device-bonus-preview :device-id="detail.id" />
|
|
|
|
</collapse-panel>
|
2025-04-02 21:02:39 +08:00
|
|
|
</el-card>
|
|
|
|
</el-col>
|
|
|
|
</el-row>
|
|
|
|
|
|
|
|
<el-card class="box-card" v-if="detail.id">
|
2025-04-10 14:07:21 +08:00
|
|
|
<el-tabs >
|
|
|
|
<el-tab-pane label="设备轨迹" lazy v-if="checkPermi(['bst:locationLog:list'])">
|
2025-04-04 18:13:14 +08:00
|
|
|
<device-location :query="{ eqMac: detail.mac }" :area-id="detail.areaId" />
|
2025-04-03 20:54:17 +08:00
|
|
|
</el-tab-pane>
|
2025-04-10 14:07:21 +08:00
|
|
|
<el-tab-pane label="命令日志" lazy v-if="checkPermi(['bst:commandLog:list'])">
|
2025-04-03 20:54:17 +08:00
|
|
|
<command-log :query="{ eqMac: detail.mac }" />
|
2025-04-02 21:02:39 +08:00
|
|
|
</el-tab-pane>
|
2025-04-10 14:07:21 +08:00
|
|
|
<el-tab-pane label="订单使用记录" lazy v-if="checkPermi(['bst:orderDevice:list'])">
|
2025-04-02 21:02:39 +08:00
|
|
|
<order-device :query="{ deviceId: id }" />
|
|
|
|
</el-tab-pane>
|
|
|
|
</el-tabs>
|
|
|
|
</el-card>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script>
|
|
|
|
import { getDevice } from '@/api/bst/device';
|
|
|
|
import { unlockDevice, lockDevice, ringDevice, rebootDevice, unlockSeatDevice, refreshDevice } from "@/api/bst/deviceIot";
|
|
|
|
import { outDevice, inDevice, disableDevice, enableDevice } from "@/api/bst/device";
|
|
|
|
import CollapsePanel from '@/components/CollapsePanel/index.vue';
|
|
|
|
import BooleanTag from '@/components/BooleanTag/index.vue';
|
|
|
|
import { DeviceStatus } from '@/utils/enums';
|
|
|
|
import { $device } from '@/views/bst/device/mixins';
|
|
|
|
import OrderDevice from '@/views/bst/orderDevice/index.vue';
|
2025-04-03 20:54:17 +08:00
|
|
|
import DeviceLocation from '@/views/bst/device/view/components/DeviceLocation.vue';
|
|
|
|
import CommandLog from '@/views/bst/commandLog/index.vue';
|
2025-04-10 14:07:21 +08:00
|
|
|
import DeviceBonusPreview from '@/views/bst/device/view/components/DeviceBonusPreview.vue';
|
2025-04-02 21:02:39 +08:00
|
|
|
|
|
|
|
export default {
|
|
|
|
name: 'DeviceView',
|
|
|
|
mixins: [$device],
|
|
|
|
dicts: ['device_status', 'device_lock_status', 'device_online_status', 'device_quality', 'device_iot_status', 'order_status', 'order_device_status'],
|
|
|
|
components: {
|
|
|
|
CollapsePanel,
|
|
|
|
BooleanTag,
|
2025-04-03 20:54:17 +08:00
|
|
|
OrderDevice,
|
|
|
|
DeviceLocation,
|
2025-04-10 14:07:21 +08:00
|
|
|
CommandLog,
|
|
|
|
DeviceBonusPreview
|
2025-04-02 21:02:39 +08:00
|
|
|
},
|
|
|
|
data() {
|
|
|
|
return {
|
|
|
|
id: null,
|
|
|
|
detail: {},
|
|
|
|
loading: false,
|
|
|
|
DeviceStatus
|
|
|
|
}
|
|
|
|
},
|
|
|
|
created() {
|
|
|
|
this.id = this.$route.params.id;
|
|
|
|
this.getDetail();
|
|
|
|
},
|
|
|
|
methods: {
|
2025-04-03 20:54:17 +08:00
|
|
|
// 获取设备详情
|
2025-04-02 21:02:39 +08:00
|
|
|
getDetail() {
|
|
|
|
this.loading = true;
|
|
|
|
getDevice(this.id).then(res => {
|
|
|
|
this.detail = res.data;
|
|
|
|
}).finally(() => {
|
|
|
|
this.loading = false;
|
|
|
|
});
|
|
|
|
},
|
|
|
|
// 管理员开锁
|
|
|
|
handleUnlock() {
|
|
|
|
this.$confirm('是否确认操作设备【' + this.detail.sn + '】开锁?', {
|
|
|
|
confirmButtonText: '确定',
|
|
|
|
cancelButtonText: '取消',
|
|
|
|
type: 'warning'
|
|
|
|
}).then(() => {
|
|
|
|
unlockDevice({ id: this.detail.id }).then((res) => {
|
|
|
|
if (res.code === 200) {
|
|
|
|
this.$message.success("操作成功,设备已开锁");
|
|
|
|
this.getDetail();
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}).catch(() => {});
|
|
|
|
},
|
|
|
|
// 管理员锁车
|
|
|
|
handleLock() {
|
|
|
|
this.$confirm('是否确认操作设备【' + this.detail.sn + '】锁车?', {
|
|
|
|
confirmButtonText: '确定',
|
|
|
|
cancelButtonText: '取消',
|
|
|
|
type: 'warning'
|
|
|
|
}).then(() => {
|
|
|
|
lockDevice({ id: this.detail.id }).then((res) => {
|
|
|
|
if (res.code === 200) {
|
|
|
|
this.$message.success("操作成功,设备已锁车");
|
|
|
|
this.getDetail();
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}).catch(() => {});
|
|
|
|
},
|
|
|
|
// 管理员响铃寻车
|
|
|
|
handleRing() {
|
|
|
|
this.$confirm('是否确认操作设备【' + this.detail.sn + '】响铃寻车?', {
|
|
|
|
confirmButtonText: '确定',
|
|
|
|
cancelButtonText: '取消',
|
|
|
|
type: 'warning'
|
|
|
|
}).then(() => {
|
|
|
|
ringDevice({ id: this.detail.id }).then((res) => {
|
|
|
|
if (res.code === 200) {
|
|
|
|
this.$message.success("操作成功,设备已响铃");
|
|
|
|
this.getDetail();
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}).catch(() => {});
|
|
|
|
},
|
|
|
|
// 管理员重启
|
|
|
|
handleReboot() {
|
|
|
|
this.$confirm('是否确认操作设备【' + this.detail.sn + '】重启?', {
|
|
|
|
confirmButtonText: '确定',
|
|
|
|
cancelButtonText: '取消',
|
|
|
|
type: 'warning'
|
|
|
|
}).then(() => {
|
|
|
|
rebootDevice({ id: this.detail.id }).then((res) => {
|
|
|
|
if (res.code === 200) {
|
|
|
|
this.$message.success("操作成功,设备已重启");
|
|
|
|
this.getDetail();
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}).catch(() => {});
|
|
|
|
},
|
|
|
|
// 管理员开坐垫锁
|
|
|
|
handleUnlockSeat() {
|
|
|
|
this.$confirm('是否确认操作设备【' + this.detail.sn + '】开坐垫锁?', {
|
|
|
|
confirmButtonText: '确定',
|
|
|
|
cancelButtonText: '取消',
|
|
|
|
type: 'warning'
|
|
|
|
}).then(() => {
|
|
|
|
unlockSeatDevice({ id: this.detail.id }).then((res) => {
|
|
|
|
if (res.code === 200) {
|
|
|
|
this.$message.success("操作成功,坐垫锁已开");
|
|
|
|
this.getDetail();
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}).catch(() => {});
|
|
|
|
},
|
|
|
|
// 管理员刷新
|
|
|
|
handleRefresh() {
|
2025-04-03 20:54:17 +08:00
|
|
|
this.loading = true;
|
|
|
|
refreshDevice({ id: this.detail.id }).then((res) => {
|
|
|
|
if (res.code === 200) {
|
|
|
|
this.$message.success("操作成功,设备已刷新");
|
|
|
|
this.detail = res.data;
|
|
|
|
}
|
|
|
|
}).finally(() => {
|
|
|
|
this.loading = false;
|
|
|
|
});
|
2025-04-02 21:02:39 +08:00
|
|
|
},
|
|
|
|
// 出仓
|
|
|
|
handleOut() {
|
|
|
|
this.$confirm('是否确认出仓设备【' + this.detail.sn + '】?', {
|
|
|
|
confirmButtonText: '确定',
|
|
|
|
cancelButtonText: '取消',
|
|
|
|
type: 'warning'
|
|
|
|
}).then(() => {
|
|
|
|
outDevice([this.detail.id]).then((res) => {
|
|
|
|
if (res.code === 200) {
|
|
|
|
this.$message.success("操作成功,设备已出仓");
|
|
|
|
this.getDetail();
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}).catch(() => {});
|
|
|
|
},
|
|
|
|
// 入仓
|
|
|
|
handleIn() {
|
|
|
|
this.$confirm('是否确认入仓设备【' + this.detail.sn + '】?', {
|
|
|
|
confirmButtonText: '确定',
|
|
|
|
cancelButtonText: '取消',
|
|
|
|
type: 'warning'
|
|
|
|
}).then(() => {
|
|
|
|
inDevice([this.detail.id]).then((res) => {
|
|
|
|
if (res.code === 200) {
|
|
|
|
this.$message.success("操作成功,设备已入仓");
|
|
|
|
this.getDetail();
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}).catch(() => {});
|
|
|
|
},
|
|
|
|
// 禁用
|
|
|
|
handleDisable() {
|
|
|
|
this.$confirm('是否确认禁用设备【' + this.detail.sn + '】?', {
|
|
|
|
confirmButtonText: '确定',
|
|
|
|
cancelButtonText: '取消',
|
|
|
|
type: 'warning'
|
|
|
|
}).then(() => {
|
|
|
|
disableDevice([this.detail.id]).then((res) => {
|
|
|
|
if (res.code === 200) {
|
|
|
|
this.$message.success("操作成功,设备已禁用");
|
|
|
|
this.getDetail();
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}).catch(() => {});
|
|
|
|
},
|
|
|
|
// 启用
|
|
|
|
handleEnable() {
|
|
|
|
this.$confirm('是否确认启用设备【' + this.detail.sn + '】?', {
|
|
|
|
confirmButtonText: '确定',
|
|
|
|
cancelButtonText: '取消',
|
|
|
|
type: 'warning'
|
|
|
|
}).then(() => {
|
|
|
|
enableDevice([this.detail.id]).then((res) => {
|
|
|
|
if (res.code === 200) {
|
|
|
|
this.$message.success("操作成功,设备已启用");
|
|
|
|
this.getDetail();
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}).catch(() => {});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
.button-group {
|
|
|
|
display: flex;
|
|
|
|
justify-content: flex-end;
|
|
|
|
margin-bottom: 10px;
|
|
|
|
}
|
|
|
|
</style>
|