he wei
2025-04-23 b9bd29a1a81f6f7de479e3cc3fdfe3d85fc660bf
src/views/device/keys/index.vue
@@ -1,180 +1,417 @@
<script setup name="KeyManage">
import { ref, onMounted, reactive, computed } from 'vue';
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 store from '@/store';
import { useUserStore } from '@/store/user.js';
const userStore = useUserStore();
const { urole, permits } = storeToRefs(userStore);
import { Search, Plus } from "@element-plus/icons-vue";
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 {
  getAllKeyList,
  addKey,
  delKey,
   addCard,
   cancleIdCard,
   delCard,
} from '@/api/keys.js';
const dialogTitle = ref('添加钥匙');
const addEditVisible = ref(false);
const background = ref(true);
const disabled = ref(false);
const dialogTitle = ref('');
const rowCardList = ref([]);
const isAdd = ref(false);
const isUnbind = ref(false);
const { $loading, $message, $confirm } = useElement();
const pageCurr = ref(1);
const pageSize = ref(10);
const total = ref(0);
const page = reactive({
      pageNum: 1,
      pageSize: 20,
      total: 0,
   });
const tableData = ref([]);
const datas = reactive({
  tableData: [],
  keyInfo: {},
   tableData: [],
   keyInfo: {},
});
const urole = computed(() => {
  return store.user().urole;
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;
  getList();
   addEditVisible.value = false;
   sendMessage();
}
function onCanel() {
  addEditVisible.value = false;
   addEditVisible.value = false;
}
// 是否有控制权限
let isCanControl = isHasPermit("control_permit", permits.value);
const filter = reactive({
  keyName: '',
  userName: ''
});
      name: "",
      state: undefined,
      type: undefined,
   });
function add() {
  dialogTitle.value = '添加钥匙';
  datas.keyInfo = {};
  addEditVisible.value = true;
}
function del(scope) {
  $confirm('删除该钥匙', () => {
    let loading = $loading();
    delKey(scope.row.keyId).then((res) => {
      let { code, data } = res;
      if (code && data) {
        $message({
          type: 'success',
          message: '删除成功!'
        });
        getList();
      } else {
        $message({
          type: 'error',
          message: '删除失败!'
        });
      }
   $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;
   dialogTitle.value = '编辑钥匙';
   datas.keyInfo = scope.row;
   // console.log('edit', scope.row, '=============');
   addEditVisible.value = true;
}
function getList() {
  //  keyName, pageNum, pageSize, uname
  let params = {
    pageNum: pageCurr.value,
    pageSize: pageSize.value,
    keyName: filter.keyName || undefined,
    uname: filter.userName || undefined
  };
  let loading = $loading();
  getAllKeyList(params).then((res) => {
    let { code, data, data2 } = res;
    let _total = 0;
    let _list = [];
    if (code && data) {
      let { list, total } = data2;
      _list = list.map(v => {
        v.type = { 1: 'ID钥匙', 2: '机械钥匙' }[v.keyType];
        return v;
      });
      _total = total;
    }
    datas.tableData = _list;
    total.value = _total;
    loading.close();
  })
    .catch((err) => {
      console.log(err);
      loading.close();
    });
}
function handleSizeChange(val) {
  pageSize.value = val;
  getList();
   pageSize.value = val;
   sendMessage();
}
function handleCurrentChange(val) {
  pageCurr.value = val;
  getList();
   pageCurr.value = val;
   sendMessage();
}
onMounted(() => {
  getList();
   sendMessage();
});
</script>
<template>
  <div class="page-wrapper">
    <div class="page-header">
    </div>
    <div class="page-header"></div>
    <div class="page-content">
      <hdw-card is-full>
      <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>
            |
            <!-- <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-label">省:</div>
                <div class="filter-content">
                  <el-input v-model="filter.keyName" size="small" @input="getList"></el-input>
                  <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-label">市:</div>
                <div class="filter-content">
                  <el-input v-model="filter.userName" size="small" @input="getList"></el-input>
                  <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" :icon="Search" @click="getList">查询</el-button>
            <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="datas.tableData" border style="width: 100%; height: 100%">
                  <el-table-column type="index" width="50" />
                  <el-table-column prop="type" align="center" label="钥匙类型" width="120" />
                  <el-table-column prop="keyName" align="center" label="钥匙名称" width="180" />
                  <el-table-column prop="keyNumber" align="center" label="钥匙编号" width="180" />
                  <el-table-column prop="uname" align="center" label="保管人" width="180" />
                  <el-table-column prop="createTime" label="创建时间" />
                  <el-table-column align="center" fixed="right" label="操作" width="180" v-if="urole > 0">
                <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="primary" size="small" @click="edit(scope)">编辑</el-button>
                      <el-button type="danger" size="small" @click="del(scope)">删除</el-button>
                      <!-- <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>
@@ -184,22 +421,44 @@
          <div class="page-content-page">
            <div class="page-tool"></div>
            <div class="el-page-container">
              <el-pagination v-model:current-page="pageCurr" v-model:page-size="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="total"
                @size-change="handleSizeChange" @current-change="handleCurrentChange" />
              <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>
      </hdw-card>
      </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" @success="onOk" :info="datas.keyInfo" @cancel="onCanel"></add-edit>
    </el-dialog>
    <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>