|
@@ -1,6 +1,11 @@
|
|
|
<template>
|
|
|
<div class="set-background">
|
|
|
<div class="block">
|
|
|
+ <el-tabs v-model="activeName" type="card" @tab-click="handleClick">
|
|
|
+ <el-tab-pane label="线下环境" name="stable" />
|
|
|
+ <el-tab-pane label="预发环境" name="preOnline" />
|
|
|
+ <el-tab-pane label="线上环境" name="online" />
|
|
|
+ </el-tabs>
|
|
|
<el-form :model="listQuery">
|
|
|
<div class="set-head">
|
|
|
<el-input v-model="listQuery.vehicleId" size="medium" clearable placeholder="车辆ID" style="width:15%;" />
|
|
@@ -17,8 +22,8 @@
|
|
|
</el-select>
|
|
|
</div>
|
|
|
<div class="set-between">
|
|
|
- <el-button type="primary" size="medium" plain @click="getDevicesList(listQuery)">搜索</el-button>
|
|
|
- <el-button type="primary" size="medium" plain @click="dialogFormVisible = true, createdCode()">新增</el-button>
|
|
|
+ <el-button type="primary" size="medium" plain @click="queryDataByEvn(listQuery)">搜索</el-button>
|
|
|
+ <el-button v-if="isStable" type="primary" size="medium" plain @click="dialogFormVisible = true, createdCode()">新增</el-button>
|
|
|
</div>
|
|
|
</el-form>
|
|
|
<div class="set-locate">
|
|
@@ -60,15 +65,15 @@
|
|
|
</el-table-column>
|
|
|
<el-table-column label="关锁" align="center" min-width="60px" class-name="small-padding fixed-width">
|
|
|
<template slot-scope="{row}">
|
|
|
- <i v-if="row.lockStatus === 1 || row.lockStatus === 4" style="font-size: 20px;" class="el-icon-lock" @click="handleLockStatus(row, 0)" />
|
|
|
+ <i v-if="row.lockStatus === 1 || row.lockStatus === 4" style="font-size: 20px;" class="el-icon-lock" @click="unLockByEvn(row, 0)" />
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
- <el-table-column label="操作" align="center" min-width="270px" class-name="small-padding fixed-width">
|
|
|
+ <el-table-column label="操作" align="center" min-width="250px" class-name="small-padding fixed-width">
|
|
|
<template slot-scope="{row}">
|
|
|
- <el-button v-if="row.isOnline === 0 || row.isOnline === 2 || row.isOnline === 3" plain size="mini" type="success" @click="handleDeviceStatus(row, 1)">激活</el-button>
|
|
|
- <el-button v-if="row.isOnline==1" plain size="mini" type="info" @click="handleDeviceStatus(row, 0)">下线</el-button>
|
|
|
+ <el-button v-if="row.isOnline === 0 || row.isOnline === 2 || row.isOnline === 3" plain size="mini" type="success" @click="activateOrOffvirtualByEvn(row, 1)">激活</el-button>
|
|
|
+ <el-button v-if="row.isOnline==1" plain size="mini" type="info" @click="activateOrOffvirtualByEvn(row, 0)">下线</el-button>
|
|
|
<el-button type="primary" plain size="mini" @click="handleUpdate(row)">编辑</el-button>
|
|
|
- <el-button type="danger" size="mini" @click="deleteCodeData(row)">删除</el-button>
|
|
|
+ <el-button v-if="isStableDel" type="danger" size="mini" @click="deleteCodeData(row)">删除</el-button>
|
|
|
<!-- <el-button v-if="row.lockStatus===1 || row.lockStatus ===4" size="mini" type="info" @click="handleLockStatus(row, 0)">关锁</el-button> -->
|
|
|
|
|
|
<!-- el-icon-lock -->
|
|
@@ -81,8 +86,12 @@
|
|
|
<!-- 查看二维码 -->
|
|
|
<el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogForUrl" width="400px" :center="true" :destroy-on-close="true" @close="closeDialog">
|
|
|
<div v-if="data_close" ref="qrcodeContainer" class="qrcode" style="margin-left:13%;margin-top:-3%" />
|
|
|
- <div style="font-size:16px;margin-left:32%;margin-top:5%;height:25px">
|
|
|
- 车辆ID:{{ urlData.vehicleId }}
|
|
|
+ <div style="font-size:16px;margin-left:32%;margin-top:5%;height:0px">
|
|
|
+ 车辆ID: {{ urlData.vehicleId }}
|
|
|
+ </div>
|
|
|
+ <div style="font-size:16px;margin-left:20%;margin-top:3%;height:30px">
|
|
|
+ <br>
|
|
|
+ (手动输码请输)锁ID: {{ urlData.lockNo }}
|
|
|
</div>
|
|
|
|
|
|
</el-dialog>
|
|
@@ -224,7 +233,7 @@
|
|
|
<br><br><br>
|
|
|
<div slot="footer" class="dialog-footer">
|
|
|
<el-button @click="dialogUpdateVisible = false">取消</el-button>
|
|
|
- <el-button v-if="showSubmitBtn" type="primary" @click="updateData(serviceData)">确定</el-button>
|
|
|
+ <el-button v-if="showSubmitBtn" type="primary" @click="updateDataByEvn(serviceData)">确定</el-button>
|
|
|
</div>
|
|
|
</el-dialog>
|
|
|
|
|
@@ -233,6 +242,8 @@
|
|
|
|
|
|
<script>
|
|
|
import { queryLockCreateInfo, queryVehicleCreateInfo, createDevice, deleteDevice, deviceOnline, deviceOffline, unlockVehicle, lockVehicle, updateLockAttr, getDevices } from '@/api/htVehicle'
|
|
|
+import { deviceOnline1, deviceOffline1, unlockVehicle1, lockVehicle1, updateLockAttr1, getDevices1 } from '@/api/htVehicle_preonline'
|
|
|
+import { deviceOnline2, deviceOffline2, unlockVehicle2, lockVehicle2, updateLockAttr2, getDevices2 } from '@/api/htVehicle_online'
|
|
|
import waves from '@/directive/waves' // waves directive
|
|
|
import { parseTime } from '@/utils'
|
|
|
import QRCode from 'qrcodejs2'
|
|
@@ -280,8 +291,9 @@ export default {
|
|
|
url: '查看二维码'
|
|
|
},
|
|
|
urlData: '',
|
|
|
+ activeName: 'stable',
|
|
|
statusMaps: new Map([[0, '离线'], [1, '连接成功'], [2, '连接失败'], [3, '连接中']]),
|
|
|
- lockStatusMaps: new Map([[1, '已开锁'], [0, '已关锁'], [2, '开锁失败'], [3, '关锁成功'], [4, '关锁失败']]),
|
|
|
+ lockStatusMaps: new Map([[1, '已开锁'], [0, '已关锁'], [2, '开锁失败'], [3, '关锁成功'], [4, '关锁失败'], [5, '关锁中']]),
|
|
|
statusOperateMaps: new Map([[1, '在线'], [0, '离线']]),
|
|
|
options: [{ value: 1, label: '在线' }, { value: 0, label: '离线' }],
|
|
|
bizType: [{ value: 1, label: '电单车' }, { value: 2, label: '单车' }],
|
|
@@ -291,6 +303,8 @@ export default {
|
|
|
lockSupplierList: [],
|
|
|
bikeModelList: [],
|
|
|
bikeSupplierList: [],
|
|
|
+ isStable: true,
|
|
|
+ isStableDel: true,
|
|
|
listQuery: {
|
|
|
// lockModel: '',
|
|
|
// isOnline: '',
|
|
@@ -364,6 +378,25 @@ export default {
|
|
|
closeDialog() {
|
|
|
this.data_close = false // 清空数据
|
|
|
},
|
|
|
+ // 切换tab
|
|
|
+ handleClick(tab, event) {
|
|
|
+ this.activeName === tab
|
|
|
+ this.listQuery = {}
|
|
|
+ console.log(this.activeName)
|
|
|
+ if (this.activeName === 'preOnline') {
|
|
|
+ this.isStable = false
|
|
|
+ this.isStableDel = false
|
|
|
+ return this.getMyDevicesList1()
|
|
|
+ } else if (this.activeName === 'online') {
|
|
|
+ this.isStable = false
|
|
|
+ this.isStableDel = false
|
|
|
+ return this.getMyDevicesList2()
|
|
|
+ } else {
|
|
|
+ this.isStable = true
|
|
|
+ this.isStableDel = true
|
|
|
+ return this.getMyDevicesList()
|
|
|
+ }
|
|
|
+ },
|
|
|
|
|
|
// 查看设备详情
|
|
|
deviceDetails(vel) {
|
|
@@ -405,7 +438,7 @@ export default {
|
|
|
})
|
|
|
},
|
|
|
|
|
|
- // 搜索
|
|
|
+ // 搜索-stable
|
|
|
getDevicesList(vel) {
|
|
|
this.listQuery = vel
|
|
|
this.listQuery.pageSize = this.pageSize
|
|
@@ -416,7 +449,39 @@ export default {
|
|
|
this.total = response.data.total
|
|
|
})
|
|
|
},
|
|
|
- // 进首页
|
|
|
+ // 根据环境来搜索
|
|
|
+ queryDataByEvn(ele) {
|
|
|
+ if (this.activeName === 'preOnline') {
|
|
|
+ return this.getDevicesList1(ele)
|
|
|
+ } else if (this.activeName === 'online') {
|
|
|
+ return this.getDevicesList2(ele)
|
|
|
+ } else {
|
|
|
+ return this.getDevicesList(ele)
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 搜索-pre
|
|
|
+ getDevicesList1(vel) {
|
|
|
+ this.listQuery = vel
|
|
|
+ this.listQuery.pageSize = this.pageSize
|
|
|
+ this.listQuery.page = this.page
|
|
|
+
|
|
|
+ getDevices1(this.listQuery).then(response => {
|
|
|
+ this.list = response.data.bikeDeviceInfos
|
|
|
+ this.total = response.data.total
|
|
|
+ })
|
|
|
+ },
|
|
|
+ // 搜索-online
|
|
|
+ getDevicesList2(vel) {
|
|
|
+ this.listQuery = vel
|
|
|
+ this.listQuery.pageSize = this.pageSize
|
|
|
+ this.listQuery.page = this.page
|
|
|
+
|
|
|
+ getDevices2(this.listQuery).then(response => {
|
|
|
+ this.list = response.data.bikeDeviceInfos
|
|
|
+ this.total = response.data.total
|
|
|
+ })
|
|
|
+ },
|
|
|
+ // 进首页-stable
|
|
|
getMyDevicesList() {
|
|
|
this.listQuery.pageSize = this.pageSize
|
|
|
this.listQuery.page = this.page
|
|
@@ -429,6 +494,42 @@ export default {
|
|
|
console.log(this.list)
|
|
|
})
|
|
|
},
|
|
|
+ // 进首页-pre
|
|
|
+ getMyDevicesList1() {
|
|
|
+ this.listQuery.pageSize = this.pageSize
|
|
|
+ this.listQuery.page = this.page
|
|
|
+ getDevices1(this.listQuery).then(response => {
|
|
|
+ // this.list = response.data.bikeDeviceInfos.map(value => value.bikeDeviceAttrInfo)
|
|
|
+ this.list = response.data.bikeDeviceInfos
|
|
|
+ this.serviceData = response.data.bikeDeviceInfos
|
|
|
+ this.detailData = response.data.bikeDeviceInfos
|
|
|
+ this.total = response.data.total
|
|
|
+ console.log(this.list)
|
|
|
+ })
|
|
|
+ },
|
|
|
+ // 进首页-online
|
|
|
+ getMyDevicesList2() {
|
|
|
+ this.listQuery.pageSize = this.pageSize
|
|
|
+ this.listQuery.page = this.page
|
|
|
+ getDevices2(this.listQuery).then(response => {
|
|
|
+ // this.list = response.data.bikeDeviceInfos.map(value => value.bikeDeviceAttrInfo)
|
|
|
+ this.list = response.data.bikeDeviceInfos
|
|
|
+ this.serviceData = response.data.bikeDeviceInfos
|
|
|
+ this.detailData = response.data.bikeDeviceInfos
|
|
|
+ this.total = response.data.total
|
|
|
+ console.log(this.list)
|
|
|
+ })
|
|
|
+ },
|
|
|
+ // 根据环境来编辑
|
|
|
+ updateDataByEvn(ele) {
|
|
|
+ if (this.activeName === 'preOnline') {
|
|
|
+ return this.updateData1(ele)
|
|
|
+ } else if (this.activeName === 'online') {
|
|
|
+ return this.updateData2(ele)
|
|
|
+ } else {
|
|
|
+ return this.updateData(ele)
|
|
|
+ }
|
|
|
+ },
|
|
|
// 编辑
|
|
|
handleUpdate(vel) {
|
|
|
console.log(vel)
|
|
@@ -437,6 +538,7 @@ export default {
|
|
|
this.dialogUpdateVisible = true
|
|
|
this.$refs.serviceDataForms.resetFields()
|
|
|
},
|
|
|
+ // 编辑-stable
|
|
|
updateData(vel) {
|
|
|
this.bizData = {
|
|
|
deviceId: vel.deviceId,
|
|
@@ -454,6 +556,42 @@ export default {
|
|
|
}
|
|
|
})
|
|
|
},
|
|
|
+ // 编辑-pre
|
|
|
+ updateData1(vel) {
|
|
|
+ this.bizData = {
|
|
|
+ deviceId: vel.deviceId,
|
|
|
+ lockBatteryLevel: vel.lockBatteryLevel,
|
|
|
+ deviceLat: vel.deviceLat,
|
|
|
+ deviceLng: vel.deviceLng
|
|
|
+ }
|
|
|
+ updateLockAttr1(this.bizData).then(response => {
|
|
|
+ if (response.code === 200) {
|
|
|
+ this.getMyDevicesList1()
|
|
|
+ this.dialogUpdateVisible = false
|
|
|
+ this.$notify({ title: 'Success', message: response.msg, type: 'success', duration: 3000 })
|
|
|
+ } else {
|
|
|
+ this.$notify({ title: 'Failed', message: response.msg, type: 'error', duration: 3000 })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ // 编辑-online
|
|
|
+ updateData2(vel) {
|
|
|
+ this.bizData = {
|
|
|
+ deviceId: vel.deviceId,
|
|
|
+ lockBatteryLevel: vel.lockBatteryLevel,
|
|
|
+ deviceLat: vel.deviceLat,
|
|
|
+ deviceLng: vel.deviceLng
|
|
|
+ }
|
|
|
+ updateLockAttr2(this.bizData).then(response => {
|
|
|
+ if (response.code === 200) {
|
|
|
+ this.getMyDevicesList2()
|
|
|
+ this.dialogUpdateVisible = false
|
|
|
+ this.$notify({ title: 'Success', message: response.msg, type: 'success', duration: 3000 })
|
|
|
+ } else {
|
|
|
+ this.$notify({ title: 'Failed', message: response.msg, type: 'error', duration: 3000 })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
// 删除设备
|
|
|
explain() {
|
|
|
if (this.showexplain === false) {
|
|
@@ -488,8 +626,18 @@ export default {
|
|
|
}
|
|
|
})
|
|
|
},
|
|
|
+ // 根据环境上下线
|
|
|
+ activateOrOffvirtualByEvn(row, status) {
|
|
|
+ if (this.activeName === 'preOnline') {
|
|
|
+ return this.handleDeviceStatus1(row, status)
|
|
|
+ } else if (this.activeName === 'online') {
|
|
|
+ return this.handleDeviceStatus2(row, status)
|
|
|
+ } else {
|
|
|
+ return this.handleDeviceStatus(row, status)
|
|
|
+ }
|
|
|
+ },
|
|
|
|
|
|
- // 设备上线、下线调用
|
|
|
+ // 设备上线、下线调用-stable
|
|
|
handleDeviceStatus(row, isOnline) {
|
|
|
if (isOnline === 1) {
|
|
|
deviceOnline(row.lockNo).then(response => {
|
|
@@ -515,8 +663,69 @@ export default {
|
|
|
})
|
|
|
}
|
|
|
},
|
|
|
-
|
|
|
- // 点击锁开启,关闭时调用
|
|
|
+ // 设备上线、下线调用-pre
|
|
|
+ handleDeviceStatus1(row, isOnline) {
|
|
|
+ if (isOnline === 1) {
|
|
|
+ deviceOnline1(row.lockNo).then(response => {
|
|
|
+ console.log('关锁' + response)
|
|
|
+ if (response.code === 200) {
|
|
|
+ row.isOnline = isOnline
|
|
|
+ this.$message({ message: '锁ID:' + row.lockNo.toString() + ' ' + this.statusOperateMaps.get(isOnline) + '成功!', type: 'success' })
|
|
|
+ } else {
|
|
|
+ this.$message({ message: '锁ID:' + row.lockNo.toString() + ' ' + this.statusOperateMaps.get(isOnline) + '失败!' + '原因:' + response.msg.toString(), type: 'danger' })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ if (isOnline === 0) {
|
|
|
+ deviceOffline1(row.deviceId).then(response => {
|
|
|
+ console.log('关锁' + response)
|
|
|
+ if (response.code === 200) {
|
|
|
+ row.isOnline = isOnline
|
|
|
+ this.$message({ message: '锁ID:' + row.lockNo.toString() + ' ' + this.statusOperateMaps.get(isOnline) + '成功!', type: 'success' })
|
|
|
+ } else {
|
|
|
+ this.$message({ message: '锁ID:' + row.lockNo.toString() + ' ' + this.statusOperateMaps.get(isOnline) + '失败!' + '原因:' + response.msg.toString(), type: 'danger' })
|
|
|
+ console.log(response)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 设备上线、下线调用-online
|
|
|
+ handleDeviceStatus2(row, isOnline) {
|
|
|
+ if (isOnline === 1) {
|
|
|
+ deviceOnline2(row.lockNo).then(response => {
|
|
|
+ console.log('关锁' + response)
|
|
|
+ if (response.code === 200) {
|
|
|
+ row.isOnline = isOnline
|
|
|
+ this.$message({ message: '锁ID:' + row.lockNo.toString() + ' ' + this.statusOperateMaps.get(isOnline) + '成功!', type: 'success' })
|
|
|
+ } else {
|
|
|
+ this.$message({ message: '锁ID:' + row.lockNo.toString() + ' ' + this.statusOperateMaps.get(isOnline) + '失败!' + '原因:' + response.msg.toString(), type: 'danger' })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ if (isOnline === 0) {
|
|
|
+ deviceOffline2(row.deviceId).then(response => {
|
|
|
+ console.log('关锁' + response)
|
|
|
+ if (response.code === 200) {
|
|
|
+ row.isOnline = isOnline
|
|
|
+ this.$message({ message: '锁ID:' + row.lockNo.toString() + ' ' + this.statusOperateMaps.get(isOnline) + '成功!', type: 'success' })
|
|
|
+ } else {
|
|
|
+ this.$message({ message: '锁ID:' + row.lockNo.toString() + ' ' + this.statusOperateMaps.get(isOnline) + '失败!' + '原因:' + response.msg.toString(), type: 'danger' })
|
|
|
+ console.log(response)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 根据环境来关锁
|
|
|
+ unLockByEvn(row, status) {
|
|
|
+ if (this.activeName === 'preOnline') {
|
|
|
+ return this.handleLockStatus1(row, status)
|
|
|
+ } else if (this.activeName === 'online') {
|
|
|
+ return this.handleLockStatus2(row, status)
|
|
|
+ } else {
|
|
|
+ return this.handleLockStatus(row, status)
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 点击锁开启,关闭时调用-stable
|
|
|
handleLockStatus(row, lockStatus) {
|
|
|
if (lockStatus === 1) {
|
|
|
unlockVehicle(row.lockNo).then(response => {
|
|
@@ -548,6 +757,70 @@ export default {
|
|
|
})
|
|
|
}
|
|
|
},
|
|
|
+ // 关锁-pre
|
|
|
+ handleLockStatus1(row, lockStatus) {
|
|
|
+ if (lockStatus === 1) {
|
|
|
+ unlockVehicle1(row.lockNo).then(response => {
|
|
|
+ if (response.code === 200) {
|
|
|
+ row.lockStatus = lockStatus
|
|
|
+ this.$message({ message: '锁ID:' + row.lockNo.toString() + ' ' + this.lockStatusMaps.get(lockStatus) + '成功!', type: 'success' })
|
|
|
+ } else {
|
|
|
+ this.$message({ message: '锁ID:' + row.lockNo.toString() + ' ' + this.lockStatusMaps.get(lockStatus) + '失败!' + '原因:' + response.msg.toString(), type: 'danger' })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ if (lockStatus === 0) {
|
|
|
+ lockVehicle1(row.lockNo).then(response => {
|
|
|
+ this.loading = true
|
|
|
+ if (response.code === 200) {
|
|
|
+ setTimeout(() => {
|
|
|
+ this.getMyDevicesList1().then(
|
|
|
+ response => {
|
|
|
+ this.list = response.data.bikeDeviceInfos
|
|
|
+ }
|
|
|
+ )
|
|
|
+ }, 1000)
|
|
|
+ row.lockStatus = lockStatus
|
|
|
+ this.loading = false
|
|
|
+ this.$message({ message: '锁ID:' + row.lockNo.toString() + ' ' + this.lockStatusMaps.get(lockStatus) + '成功!', type: 'success' })
|
|
|
+ } else {
|
|
|
+ this.$message({ message: '锁ID:' + row.lockNo.toString() + ' ' + this.lockStatusMaps.get(lockStatus) + '失败!' + '原因:' + response.msg.toString(), type: 'danger' })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 关锁-online
|
|
|
+ handleLockStatus2(row, lockStatus) {
|
|
|
+ if (lockStatus === 1) {
|
|
|
+ unlockVehicle2(row.lockNo).then(response => {
|
|
|
+ if (response.code === 200) {
|
|
|
+ row.lockStatus = lockStatus
|
|
|
+ this.$message({ message: '锁ID:' + row.lockNo.toString() + ' ' + this.lockStatusMaps.get(lockStatus) + '成功!', type: 'success' })
|
|
|
+ } else {
|
|
|
+ this.$message({ message: '锁ID:' + row.lockNo.toString() + ' ' + this.lockStatusMaps.get(lockStatus) + '失败!' + '原因:' + response.msg.toString(), type: 'danger' })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ if (lockStatus === 0) {
|
|
|
+ lockVehicle2(row.lockNo).then(response => {
|
|
|
+ this.loading = true
|
|
|
+ if (response.code === 200) {
|
|
|
+ setTimeout(() => {
|
|
|
+ this.getMyDevicesList2().then(
|
|
|
+ response => {
|
|
|
+ this.list = response.data.bikeDeviceInfos
|
|
|
+ }
|
|
|
+ )
|
|
|
+ }, 1000)
|
|
|
+ row.lockStatus = lockStatus
|
|
|
+ this.loading = false
|
|
|
+ this.$message({ message: '锁ID:' + row.lockNo.toString() + ' ' + this.lockStatusMaps.get(lockStatus) + '成功!', type: 'success' })
|
|
|
+ } else {
|
|
|
+ this.$message({ message: '锁ID:' + row.lockNo.toString() + ' ' + this.lockStatusMaps.get(lockStatus) + '失败!' + '原因:' + response.msg.toString(), type: 'danger' })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ },
|
|
|
|
|
|
// 新建点击提交时调用
|
|
|
createData(ele) {
|
|
@@ -619,8 +892,8 @@ export default {
|
|
|
background-color rgba(255,255,255,1)
|
|
|
box-shadow 0px 0px 11px 0px rgba(238,240,245,1)
|
|
|
border-radius 7px
|
|
|
- width 98%
|
|
|
- margin 10px 0
|
|
|
+ width 93%
|
|
|
+ margin 25px 0
|
|
|
padding 20px
|
|
|
min-height calc(100vh - 100px)
|
|
|
.block >>> th
|