<script setup name="KeyManage">
|
import { ref, onMounted, reactive, computed, watchEffect, nextTick } from 'vue';
|
import addEdit from './addEdit.vue';
|
import { storeToRefs } from "pinia";
|
import useElement from "@/hooks/useElement.js";
|
import { useUserStore } from '@/store/user.js';
|
const userStore = useUserStore();
|
const { urole, permits } = storeToRefs(userStore);
|
|
import useWebSocket from "@/hooks/useWebsocket.js";
|
import isHasPermit from '@/utils/isHasPermit';
|
|
const { sendData, message: listMessage } = useWebSocket("lockRt");
|
import useStation from "@/hooks/useStationList.js";
|
const { stationName1, stationName2, stationName3, stationName4,
|
stationList1, stationList2, stationList3, stationList4,
|
} = useStation();
|
|
|
import {
|
addCard,
|
cancleIdCard,
|
delCard,
|
} from '@/api/keys.js';
|
|
const addEditVisible = ref(false);
|
const background = ref(true);
|
const disabled = ref(false);
|
const dialogTitle = ref('');
|
const rowCardList = ref([]);
|
|
const isUnbind = ref(false);
|
|
const { $loading, $message, $confirm } = useElement();
|
|
const page = reactive({
|
pageNum: 1,
|
pageSize: 20,
|
total: 0,
|
});
|
const tableData = ref([]);
|
|
const datas = reactive({
|
tableData: [],
|
keyInfo: {},
|
});
|
|
const rowLockId = ref('');
|
|
function sendMessage() {
|
let params = {
|
lockName: filter.name.trim() || undefined,
|
lockState: filter.state,
|
// lockType: filter.type,
|
stationName1: stationName1.value || undefined,
|
stationName2: stationName2.value || undefined,
|
stationName3: stationName3.value || undefined,
|
stationName4: stationName4.value || undefined,
|
pageNum: page.pageNum,
|
pageSize: page.pageSize,
|
};
|
sendData(
|
JSON.stringify(params)
|
);
|
}
|
|
watchEffect(() => {
|
let _total = 0;
|
let _list = [];
|
if (listMessage.value) {
|
const {
|
code,
|
data,
|
data2
|
} = JSON.parse(listMessage.value);
|
|
if (code && data) {
|
let { list, total } = data2;
|
_list = list.map(v => {
|
let cardList = [];
|
let lockIdcard = v.lockIdcard;
|
if (lockIdcard) {
|
for (let i = 1; i <= 100; i++) {
|
if (lockIdcard[`card${i}`] != '0') {
|
cardList.push(lockIdcard[`card${i}`]);
|
}
|
}
|
}
|
v.state = { 0: '已闭锁', 1: '已开锁' }[v.lockState];
|
v.onlineState = { 0: '离线', 1: '在线' }[v.lockOnline];
|
v.type = { 1: '蓝牙锁', 2: 'ID锁', 3: '实体锁' }[v.lockType];
|
v.modelStr = v.model == 1 ? '在线模式' : '离线模式';
|
v.blStateStr = v.blState == 0 ? '蓝牙关闭' : '蓝牙开启';
|
v.ID = v.lockId % 10000000;
|
v.cardList = cardList.join(',');
|
return v;
|
});
|
_total = total;
|
}
|
}
|
tableData.value = _list;
|
page.total = _total;
|
});
|
|
function onOk() {
|
addEditVisible.value = false;
|
sendMessage();
|
}
|
|
function onCanel() {
|
addEditVisible.value = false;
|
}
|
|
// 是否有控制权限
|
let isCanControl = isHasPermit("control_permit", permits.value);
|
|
const filter = reactive({
|
name: "",
|
state: undefined,
|
type: undefined,
|
});
|
|
|
function del(scope) {
|
$confirm('删除该钥匙', () => {
|
let loading = $loading();
|
delKey(scope.row.keyId).then((res) => {
|
let { code, data } = res;
|
if (code && data) {
|
$message({
|
type: 'success',
|
message: '删除成功!'
|
});
|
sendMessage();
|
} else {
|
$message({
|
type: 'error',
|
message: '删除失败!'
|
});
|
}
|
loading.close();
|
});
|
});
|
}
|
|
function bindCard(scope) {
|
console.log('scope', scope, '=============');
|
isUnbind.value = false;
|
dialogTitle.value = '绑定电子卡';
|
rowCardList.value = scope.row.cardList.split(',');
|
rowLockId.value = scope.row.lockId;
|
addEditVisible.value = true;
|
|
}
|
|
function unBindCard(scope) {
|
console.log('scope', scope, '=============');
|
isUnbind.value = true;
|
dialogTitle.value = '解绑电子卡';
|
rowCardList.value = scope.row.cardList.split(',');
|
rowLockId.value = scope.row.lockId;
|
addEditVisible.value = true;
|
|
}
|
|
function clearCard(scope) {
|
console.log('scope', scope, '=============');
|
let { lockId } = scope.row;
|
let loading = $loading();
|
cancleIdCard(lockId).then((res) => {
|
let { code, data } = res;
|
loading.close();
|
if (code && data) {
|
// console.log(data);
|
$message.success('操作成功');
|
} else {
|
$message.error('操作失败');
|
}
|
})
|
.catch((err) => {
|
console.log(err);
|
loading.close();
|
});
|
}
|
|
function edit(scope) {
|
dialogTitle.value = '编辑钥匙';
|
datas.keyInfo = scope.row;
|
// console.log('edit', scope.row, '=============');
|
|
addEditVisible.value = true;
|
}
|
|
|
function handleSizeChange(val) {
|
pageSize.value = val;
|
sendMessage();
|
}
|
|
function handleCurrentChange(val) {
|
pageCurr.value = val;
|
sendMessage();
|
}
|
|
onMounted(() => {
|
sendMessage();
|
});
|
</script>
|
|
<template>
|
<div class="page-wrapper">
|
<div class="page-header"></div>
|
<div class="page-content">
|
<yc-card is-full>
|
<div class="page-content-wrapper">
|
<div class="page-content-tools">
|
<!-- <el-button type="primary" size="small" :icon="Plus" @click="add"
|
>添加钥匙</el-button
|
>
|
| -->
|
<div class="tools-filter">
|
<div class="tools-filter-item">
|
<div class="filter-label">省:</div>
|
<div class="filter-content">
|
<el-select
|
v-model="stationName1"
|
clearable
|
placeholder="请选择"
|
@change="() => nextTick(() => sendMessage())"
|
size="small"
|
style="width: 180px"
|
>
|
<el-option
|
v-for="(item, idx) in stationList1"
|
:key="'province_' + idx"
|
:label="item"
|
:value="item"
|
/>
|
</el-select>
|
</div>
|
</div>
|
<div class="tools-filter-item">
|
<div class="filter-label">市:</div>
|
<div class="filter-content">
|
<el-select
|
v-model="stationName2"
|
clearable
|
placeholder="请选择"
|
@change="() => nextTick(() => sendMessage())"
|
size="small"
|
style="width: 180px"
|
>
|
<el-option
|
v-for="(item, idx) in stationList2"
|
:key="'city_' + idx"
|
:label="item"
|
:value="item"
|
/>
|
</el-select>
|
</div>
|
</div>
|
<div class="tools-filter-item">
|
<div class="filter-label">区县:</div>
|
<div class="filter-content">
|
<el-select
|
v-model="stationName3"
|
clearable
|
placeholder="请选择"
|
@change="() => nextTick(() => sendMessage())"
|
size="small"
|
style="width: 180px"
|
>
|
<el-option
|
v-for="(item, idx) in stationList3"
|
:key="'list2_' + idx"
|
:label="item"
|
:value="item"
|
/>
|
</el-select>
|
</div>
|
</div>
|
<div class="tools-filter-item">
|
<div class="filter-label">机房:</div>
|
<div class="filter-content">
|
<el-select
|
v-model="stationName4"
|
clearable
|
placeholder="请选择"
|
@change="() => nextTick(() => sendMessage())"
|
size="small"
|
style="width: 180px"
|
>
|
<el-option
|
v-for="(item, idx) in stationList4"
|
:key="'list3_' + idx"
|
:label="item"
|
:value="item"
|
/>
|
</el-select>
|
</div>
|
</div>
|
|
<div class="tools-filter-item">
|
<div class="filter-label">锁具名称:</div>
|
<div class="filter-content">
|
<el-input
|
@input="sendMessage"
|
placeholder="请输入锁具名称..."
|
v-model="filter.name"
|
size="small"
|
></el-input>
|
</div>
|
</div>
|
</div>
|
<el-button
|
type="primary"
|
size="small"
|
@click="sendMessage"
|
><svg-icon icon-class="search"></svg-icon>查询</el-button
|
>
|
</div>
|
<div class="page-content-table">
|
<div class="pos-rel">
|
<div class="pos-abs">
|
<el-table
|
:data="tableData"
|
border
|
style="width: 100%; height: 100%"
|
>
|
<el-table-column fixed="left" type="index" width="50" />
|
<el-table-column
|
prop="stationName"
|
align="center"
|
label="机房名称"
|
min-width="260"
|
/>
|
<el-table-column
|
prop="lockName"
|
align="center"
|
label="锁具名称"
|
width="180"
|
/>
|
<el-table-column
|
prop="lockAddress"
|
align="center"
|
label="锁具地址"
|
width="180"
|
/>
|
<el-table-column prop="ID" label="锁ID" width="120" />
|
<el-table-column
|
prop="lockIp"
|
align="center"
|
label="IP"
|
width="180"
|
/>
|
<el-table-column
|
prop="modelStr"
|
align="center"
|
label="控制模式"
|
width="180"
|
/>
|
<el-table-column
|
prop="onlineState"
|
align="center"
|
label="在线状态"
|
width="180"
|
/>
|
<el-table-column
|
prop="blStateStr"
|
align="center"
|
label="蓝牙状态"
|
width="180"
|
/>
|
<el-table-column
|
prop="cardList"
|
align="center"
|
label="已绑定电子卡号"
|
min-width="340"
|
/>
|
<el-table-column
|
align="center"
|
fixed="right"
|
label="操作"
|
width="340"
|
v-if="urole > 0"
|
>
|
<template #default="scope">
|
<!-- <el-button type="danger" size="small"
|
v-if="isAdmin && scope.row.lockOnline == 1 && scope.row.lockState == 0"
|
@click="open(scope)">远程开锁</el-button>
|
<el-button type="primary" v-if="scope.row.blState == 0" size="small"
|
@click="edit(scope)">开启蓝牙</el-button>
|
<el-button type="primary" v-else size="small" @click="edit(scope)">关闭蓝牙</el-button> -->
|
<el-button
|
type="primary"
|
size="small"
|
v-if="isCanControl && scope.row.lockOnline == 1"
|
@click="bindCard(scope)"
|
>绑定电子卡</el-button
|
>
|
<el-button
|
type="danger"
|
size="small"
|
v-if="isCanControl && scope.row.lockOnline == 1"
|
@click="unBindCard(scope)"
|
>解绑电子卡</el-button
|
>
|
<el-button
|
type="danger"
|
size="small"
|
v-if="isCanControl && scope.row.lockOnline == 1"
|
@click="clearCard(scope)"
|
>清空电子卡</el-button
|
>
|
</template>
|
</el-table-column>
|
</el-table>
|
</div>
|
</div>
|
</div>
|
<div class="page-content-page">
|
<div class="page-tool"></div>
|
<div class="el-page-container">
|
<el-pagination
|
v-model:current-page="page.pageNum"
|
v-model:page-size="page.pageSize"
|
:page-sizes="[20, 40, 60, 80, 100, 200, 300, 400]"
|
size="small"
|
:disabled="disabled"
|
:background="background"
|
layout="total, sizes, prev, pager, next, jumper"
|
:total="page.total"
|
@size-change="handleSizeChange"
|
@current-change="handleCurrentChange"
|
/>
|
</div>
|
<div class="page-tool"></div>
|
</div>
|
</div>
|
</yc-card>
|
</div>
|
<div class="page-footer"></div>
|
<!-- 弹窗 -->
|
<el-dialog
|
:title="dialogTitle"
|
v-model="addEditVisible"
|
top="0"
|
:close-on-click-modal="false"
|
class="dialog-center"
|
width="700px"
|
center
|
>
|
<add-edit
|
v-if="addEditVisible"
|
:isUnbind="isUnbind"
|
:lockId="rowLockId"
|
@success="onOk"
|
:list="rowCardList"
|
@cancel="onCanel"
|
></add-edit>
|
</el-dialog>
|
</div>
|
</template>
|
|
<style scoped lang="scss">
|
.page-wrapper {
|
display: flex;
|
flex-direction: row;
|
padding: 8px;
|
height: 100%;
|
|
.page-content {
|
flex: 1;
|
}
|
}
|
|
.page-content-wrapper {
|
display: flex;
|
flex-direction: column;
|
height: 100%;
|
|
.page-content-tools {
|
padding-bottom: 8px;
|
}
|
|
.page-content-table {
|
flex: 1;
|
margin-left: -8px;
|
margin-right: -8px;
|
}
|
|
.page-content-page {
|
padding: 8px 8px 0 8px;
|
text-align: center;
|
|
.el-page-container {
|
display: inline-block;
|
padding: 0 16px;
|
}
|
|
.page-tool {
|
display: inline-block;
|
}
|
}
|
}
|
|
.hdw-card-container {
|
width: 240px;
|
padding-right: 8px;
|
height: 100%;
|
}
|
|
.pos-rel {
|
position: relative;
|
width: 100%;
|
height: 100%;
|
|
.pos-abs {
|
position: absolute;
|
top: 0;
|
bottom: 0;
|
left: 0;
|
right: 0;
|
width: 100%;
|
height: 100%;
|
}
|
}
|
|
.tools-filter {
|
display: inline-block;
|
font-size: 14px;
|
|
.tools-filter-item {
|
display: inline-block;
|
margin-right: 8px;
|
|
.filter-label {
|
display: inline-block;
|
}
|
|
.filter-content {
|
display: inline-block;
|
}
|
}
|
}
|
</style>
|