smart-switch-ui/src/views/system/device/detail.vue
2024-08-15 21:23:23 +08:00

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>