314 lines
12 KiB
Vue
314 lines
12 KiB
Vue
<template>
|
|
<div class="app-container" v-loading="loading" >
|
|
<div v-if="deviceData">
|
|
<el-card class="box-card" >
|
|
<el-descriptions title="设备详情" :column="4">
|
|
<template slot="extra">
|
|
<el-dropdown style="margin-right: 1em">
|
|
<el-button>
|
|
更多操作<i class="el-icon-arrow-down el-icon--right"></i>
|
|
</el-button>
|
|
<el-dropdown-menu slot="dropdown">
|
|
<el-dropdown-item>
|
|
<el-link :underline="false" icon="el-icon-plus" @click="handleAddElectricity">增加时长</el-link>
|
|
</el-dropdown-item>
|
|
<el-dropdown-item>
|
|
<el-link :underline="false" icon="el-icon-refresh" @click="handleReset">时长归零</el-link>
|
|
</el-dropdown-item>
|
|
<el-dropdown-item>
|
|
<el-link :underline="false" icon="el-icon-switch-button" v-if="!isOpen" @click="handleSwitch(true)">强制开启</el-link>
|
|
</el-dropdown-item>
|
|
<el-dropdown-item>
|
|
<el-link :underline="false" icon="el-icon-switch-button" v-if="isOpen" @click="handleSwitch(false)">强制关闭</el-link>
|
|
</el-dropdown-item>
|
|
<el-dropdown-item>
|
|
<el-link :underline="false" icon="el-icon-link" type="danger" @click="handleUnbind" :disabled="deviceData.userId == null">强制解绑</el-link>
|
|
</el-dropdown-item>
|
|
</el-dropdown-menu>
|
|
</el-dropdown>
|
|
|
|
<el-button icon="el-icon-refresh" @click="refreshIot(deviceId, true)" style="margin-right: 1em">刷新设备信息</el-button>
|
|
<el-popover
|
|
placement="left"
|
|
width="180"
|
|
trigger="click">
|
|
<div class="qr-code-box">
|
|
<qr-code :text="qrCodeText(deviceData)" :width="150" :height="150" />
|
|
<p>扫描二维码进行设备绑定</p>
|
|
</div>
|
|
<el-button slot="reference" type="primary" icon="el-icon-picture">设备二维码</el-button>
|
|
</el-popover>
|
|
</template>
|
|
<el-descriptions-item label="MAC">{{deviceData.mac | defaultValue}}
|
|
<dict-tag :options="dict.type.sm_device_status" :value="deviceData.status" size="mini"/>
|
|
</el-descriptions-item>
|
|
<el-descriptions-item label="SN">{{deviceData.deviceNo | defaultValue}}</el-descriptions-item>
|
|
<el-descriptions-item label="在线状态">
|
|
<dict-tag :options="dict.type.sm_device_online_status" :value="deviceData.onlineStatus" size="mini"/>
|
|
</el-descriptions-item>
|
|
<el-descriptions-item label="开关状态">
|
|
<el-tag :type="isOpen ? 'success' : 'danger'" size="mini">{{isOpen ? '已开启' : '已关闭'}}</el-tag>
|
|
</el-descriptions-item>
|
|
<el-descriptions-item label="型号">{{deviceData.model | defaultValue}}</el-descriptions-item>
|
|
<el-descriptions-item label="型号功能">
|
|
<dict-tag :options="dict.type.sm_model_tag" :value="deviceData.modelTags" size="mini"/>
|
|
</el-descriptions-item>
|
|
<el-descriptions-item label="设备租期">{{deviceData.rentTime | defaultValue}}</el-descriptions-item>
|
|
<el-descriptions-item label="WIFI">{{deviceData.wifi | defaultValue}}</el-descriptions-item>
|
|
<el-descriptions-item label="剩余时长">{{surplusTimeDesc(surplusTime).text}}</el-descriptions-item>
|
|
<el-descriptions-item label="设备剩余时长">
|
|
{{surplusTimeDesc(deviceData.remainTime).text}}
|
|
<span class="remark-text">最近更新时间:{{deviceData.lastPullTime}}</span>
|
|
</el-descriptions-item>
|
|
<el-descriptions-item label="设备剩余电量">
|
|
{{deviceData.surplusEle | defaultValue}} 度
|
|
</el-descriptions-item>
|
|
</el-descriptions>
|
|
</el-card>
|
|
|
|
<el-card class="box-card">
|
|
<el-descriptions title="所属人信息" :column="4">
|
|
<el-descriptions-item label="所属用户">
|
|
<user-link :name="deviceData.userName" :id="deviceData.userId"/>
|
|
</el-descriptions-item>
|
|
<el-descriptions-item label="设备名称">{{deviceData.deviceName | defaultValue}}</el-descriptions-item>
|
|
<el-descriptions-item label="店铺名称">
|
|
<store-link :name="deviceData.storeName" :id="deviceData.storeId"/>
|
|
</el-descriptions-item>
|
|
<el-descriptions-item label="服务费">
|
|
<template v-if="deviceData.serviceRate == null || deviceData.serviceType == null">跟随用户</template>
|
|
<template v-else>
|
|
<dict-tag :options="dict.type.service_type" :value="deviceData.serviceType" size="mini"/>
|
|
{{deviceData.serviceRate}} {{serviceUnit(deviceData.serviceType)}}
|
|
</template>
|
|
</el-descriptions-item>
|
|
<el-descriptions-item label="备注">{{deviceData.remark | defaultValue}}</el-descriptions-item>
|
|
</el-descriptions>
|
|
</el-card>
|
|
|
|
<el-card class="box-card">
|
|
<el-tabs>
|
|
<el-tab-pane label="套餐列表" :lazy="true">
|
|
<suit v-if="deviceData.deviceId != null" :view="views.device" :query="{deviceId: deviceData.deviceId}"/>
|
|
</el-tab-pane>
|
|
<el-tab-pane label="用户充值记录" :lazy="true">
|
|
<recharge-record :device-id="deviceData.deviceId"/>
|
|
</el-tab-pane>
|
|
<el-tab-pane label="时长变化记录" :lazy="true">
|
|
<record-time :query="{deviceId: deviceData.deviceId}" view="device"/>
|
|
</el-tab-pane>
|
|
<el-tab-pane label="抄表记录" :lazy="true">
|
|
<reading-record :device-id="deviceData.deviceId"/>
|
|
</el-tab-pane>
|
|
<el-tab-pane label="绑定记录" :lazy="true">
|
|
<bind-record :device-id="deviceData.deviceId"/>
|
|
</el-tab-pane>
|
|
</el-tabs>
|
|
</el-card>
|
|
</div>
|
|
<el-empty v-else description="设备已被删除或不存在"/>
|
|
|
|
<!--添加时长-->
|
|
<el-dialog title="增加时长" :visible.sync="showAddElectricity" center width="400px">
|
|
<el-form :model="addElectricityForm" :rules="addRules">
|
|
<el-form-item label="时长" prop="amount">
|
|
<el-input-number v-model="addElectricityForm.amount" style="width: 250px" controls-position="right" :step="1" step-strictly :min="0"/> 分钟
|
|
</el-form-item>
|
|
</el-form>
|
|
<template #footer>
|
|
<el-button type="primary" plain @click="submitAddElectricity">确认</el-button>
|
|
<el-button plain @click="showAddElectricity = false">取消</el-button>
|
|
</template>
|
|
</el-dialog>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
|
|
import { addTime, getDevice, refreshIot, resetDevice, switchDevice, unbind } from '@/api/system/device'
|
|
import LineChart from "@/views/dashboard/LineChart.vue";
|
|
import RechargeRecord from "@/views/system/device/components/rechargeRecord.vue";
|
|
import QrCode from "@/components/QrCode/index.vue";
|
|
import MeterRecordReport from "@/views/system/device/components/meterRecordReport.vue";
|
|
import ReadingRecord from "@/views/system/device/components/readingRecord.vue";
|
|
import {getWxIndexUrl} from "@/utils/wx";
|
|
import BindRecord from "@/views/system/device/components/bindRecord.vue";
|
|
import ResetRecord from "@/views/system/device/components/resetRecord.vue";
|
|
import TenantList from "@/views/system/device/components/tenantList.vue";
|
|
import SuitList from '@/views/system/device/components/suitList.vue'
|
|
import Suit from '@/views/ss/suit/index.vue'
|
|
import RecordTime from '@/views/ss/time/index.vue'
|
|
import { toDescriptionFromSecond } from '@/utils/date'
|
|
import StoreLink from '@/components/Business/Store/StoreLink.vue'
|
|
import UserLink from '@/components/Business/SmUser/UserLink.vue'
|
|
import { $serviceType, $view } from '@/utils/mixins'
|
|
|
|
export default {
|
|
name: 'Device/:deviceId',
|
|
mixins: [$serviceType, $view],
|
|
components: {
|
|
UserLink,
|
|
StoreLink,
|
|
RecordTime,
|
|
Suit,
|
|
SuitList,
|
|
TenantList, ResetRecord, BindRecord, ReadingRecord, MeterRecordReport, QrCode, RechargeRecord, LineChart},
|
|
dicts: ['sm_device_status', 'sm_device_outage_way', 'sm_device_notice_way', 'sm_model_tag', 'sm_device_online_status', 'service_type'],
|
|
data() {
|
|
return {
|
|
loading: false,
|
|
deviceData: {},
|
|
timer: null,
|
|
surplusTime: 0, // 剩余时长
|
|
addElectricityForm: {
|
|
amount: 0
|
|
},
|
|
showAddElectricity: false,
|
|
addRules: {
|
|
amount: [
|
|
{ required: true, message: '请输入电量', trigger: 'blur' }
|
|
]
|
|
},
|
|
// 设备ID
|
|
deviceId: null,
|
|
}
|
|
},
|
|
computed: {
|
|
qrCodeText() {
|
|
return (device) => {
|
|
return getWxIndexUrl({ s: device.deviceNo});
|
|
}
|
|
},
|
|
surplusTimeDesc() {
|
|
return (second) => {
|
|
return toDescriptionFromSecond(second);
|
|
}
|
|
},
|
|
isOpen() {
|
|
return this.deviceData != null && this.deviceData.powerStatus === '1';
|
|
}
|
|
},
|
|
created() {
|
|
this.deviceId = this.$route.params.deviceId;
|
|
this.refreshIot(this.deviceId);
|
|
},
|
|
beforeDestroy() {
|
|
clearInterval(this.timer);
|
|
},
|
|
methods: {
|
|
handleUnbind() {
|
|
this.$confirm('是否强制解绑该设备?', '警告', {
|
|
confirmButtonText: '确定',
|
|
cancelButtonText: '取消',
|
|
type: 'warning'
|
|
}).then(() => {
|
|
this.loading = true;
|
|
unbind(this.deviceData.deviceId).then(res => {
|
|
if (res.code === 200) {
|
|
this.$message.success("操作成功");
|
|
}
|
|
}).finally(() => {
|
|
this.getDevice();
|
|
})
|
|
})
|
|
},
|
|
handleSwitch(open) {
|
|
this.$confirm(`是否确认强制${open ? '开启' : '关闭'}设备?`, '警告', {
|
|
confirmButtonText: '确定',
|
|
cancelButtonText: '取消',
|
|
type: 'warning'
|
|
}).then(() => {
|
|
this.loading = true;
|
|
switchDevice(this.deviceData.deviceId, open).then(res => {
|
|
if (res.code === 200) {
|
|
this.$message.success("操作成功");
|
|
this.deviceData.powerStatus = open ? '1' : '0';
|
|
}
|
|
}).finally(() => {
|
|
this.loading = false;
|
|
})
|
|
})
|
|
},
|
|
// 计算剩余时长
|
|
computeSurplusTime() {
|
|
if (this.deviceData.expireTime == null) {
|
|
return 0;
|
|
}
|
|
let expireTime = new Date(this.deviceData.expireTime).getTime();
|
|
let now = new Date().getTime();
|
|
if (expireTime < now) {
|
|
return 0;
|
|
}
|
|
return ((expireTime - now) / 1000).toFixed(2);
|
|
},
|
|
handleReset() {
|
|
this.$confirm('是否确认归零设备?', '警告', {
|
|
confirmButtonText: '确定',
|
|
cancelButtonText: '取消',
|
|
type: 'warning'
|
|
}).then(() => {
|
|
resetDevice(this.deviceData.deviceId).then(res => {
|
|
if (res.code === 200) {
|
|
this.$message.success('操作成功');
|
|
this.getDevice();
|
|
}
|
|
})
|
|
})
|
|
},
|
|
handleAddElectricity() {
|
|
this.resetAddElectricityForm();
|
|
this.showAddElectricity = true;
|
|
},
|
|
submitAddElectricity() {
|
|
addTime(this.deviceData.deviceId, this.addElectricityForm.amount).then(res => {
|
|
if (res.code === 200) {
|
|
this.$message.success('操作成功');
|
|
this.showAddElectricity = false;
|
|
this.getDevice();
|
|
}
|
|
})
|
|
},
|
|
resetAddElectricityForm() {
|
|
this.addElectricityForm = {
|
|
amount: 0
|
|
}
|
|
},
|
|
// 刷新设备信息
|
|
refreshIot(deviceId, notice = false) {
|
|
this.loading = true;
|
|
refreshIot(deviceId).then(res => {
|
|
if (res.code !== 200) {
|
|
return this.$message.error(res.msg);
|
|
}
|
|
if (notice) {
|
|
this.$message.success('操作成功');
|
|
}
|
|
}).finally(() => {
|
|
this.getDevice();
|
|
})
|
|
},
|
|
getDevice() {
|
|
this.loading = true;
|
|
getDevice(this.deviceId).then(response => {
|
|
this.deviceData = response.data;
|
|
this.surplusTime = this.computeSurplusTime();
|
|
if (this.timer == null) {
|
|
this.timer = setInterval(() => {
|
|
this.surplusTime = this.computeSurplusTime();
|
|
}, 1000)
|
|
}
|
|
}).finally(() => {
|
|
this.loading = false;
|
|
})
|
|
},
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
.remark-text {
|
|
color: #ccc;
|
|
margin-left: 1em;
|
|
}
|
|
</style>
|