zouyu
昨天 6d2f26e4c867c1cfba4ebe86d4162edb01da80a0
src/views/environmentAccess/accessManagement/index.vue
@@ -1,9 +1,347 @@
<template>
  <div></div>
  <div class="app-container">
    <el-form :model="filters" :inline="true">
      <el-form-item label="门禁名称">
        <el-input
          v-model="filters.name"
          style="width: 240px"
          placeholder="请输入门禁名称"
          clearable
          :prefix-icon="Search"
          @change="getTableData"
        />
      </el-form-item>
      <el-form-item label="门禁状态">
        <el-select
          v-model="filters.status"
          style="width: 240px"
          placeholder="请选择门禁状态"
          clearable
          @change="getTableData"
        >
          <el-option label="正常" value="1"></el-option>
          <el-option label="异常" value="0"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="区域">
        <el-input
          v-model="filters.area"
          style="width: 240px"
          placeholder="请输入区域"
          clearable
          :prefix-icon="Search"
          @change="getTableData"
        />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="getTableData">搜索</el-button>
        <el-button @click="resetFilters">重置</el-button>
      </el-form-item>
    </el-form>
    <div class="table_list">
      <div class="actions">
        <div></div>
        <div>
          <el-button type="primary" @click="add" icon="Plus"> 新增 </el-button>
          <el-button type="danger" icon="Delete" :disabled="multipleList.length <= 0" @click="batchDelete">批量删除</el-button>
        </div>
      </div>
      <PIMTable
        rowKey="id"
        isSelection
        :column="columns"
        :tableData="dataList"
        :page="{
          current: pagination.currentPage,
          size: pagination.pageSize,
          total: pagination.total,
        }"
        @selection-change="handleSelectionChange"
        @pagination="changePage"
      >
      </PIMTable>
    </div>
    <!-- 新增编辑弹窗 -->
    <el-dialog v-model="dialogVisible" :title="dialogTitle" width="600px">
      <el-form :model="formData" label-width="100px">
        <el-form-item label="门禁名称" required>
          <el-input v-model="formData.name" placeholder="请输入门禁名称"></el-input>
        </el-form-item>
        <el-form-item label="区域" required>
          <el-input v-model="formData.area" placeholder="请输入区域"></el-input>
        </el-form-item>
        <el-form-item label="位置" required>
          <el-input v-model="formData.location" placeholder="请输入具体位置"></el-input>
        </el-form-item>
        <el-form-item label="状态" required>
          <el-select v-model="formData.status" placeholder="请选择状态">
            <el-option label="正常" value="1"></el-option>
            <el-option label="异常" value="0"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="描述">
          <el-input v-model="formData.description" type="textarea" rows="3" placeholder="请输入描述信息"></el-input>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="saveData">确定</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>
<script>
<script setup>
import { ref, reactive, computed, onMounted } from 'vue';
import { Search, Plus, Delete } from '@element-plus/icons-vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import dayjs from 'dayjs';
// 定义假数据
const mockData = [
  { id: 1, name: '东门门禁', area: '生产区', location: '东门入口', status: '1', lastUpdate: '2025-12-30 08:30:00', description: '主要用于员工上下班通行' },
  { id: 2, name: '西门门禁', area: '仓储区', location: '西门入口', status: '1', lastUpdate: '2025-12-30 09:15:00', description: '主要用于物流车辆通行' },
  { id: 3, name: '南门门禁', area: '办公区', location: '南门入口', status: '0', lastUpdate: '2025-12-30 10:20:00', description: '主要用于访客通行,当前故障' },
  { id: 4, name: '北门门禁', area: '生产区', location: '北门入口', status: '1', lastUpdate: '2025-12-30 11:45:00', description: '主要用于原材料运输车辆通行' },
  { id: 5, name: '中控室门禁', area: '中控区', location: '中控室门口', status: '1', lastUpdate: '2025-12-30 13:20:00', description: '仅限授权人员进入' },
];
// 响应式数据
const filters = reactive({
  name: '',
  status: '',
  area: ''
});
const dataList = ref([]);
const pagination = reactive({
  currentPage: 1,
  pageSize: 10,
  total: 0
});
const multipleList = ref([]);
const dialogVisible = ref(false);
const dialogTitle = ref('新增门禁');
const formData = reactive({
  id: '',
  name: '',
  area: '',
  location: '',
  status: '1',
  description: ''
});
// 表格列配置
const columns = [
  {
    label: '门禁名称',
    align: 'center',
    prop: 'name',
  },
  {
    label: '区域',
    align: 'center',
    prop: 'area',
  },
  {
    label: '位置',
    align: 'center',
    prop: 'location',
  },
  {
    label: '状态',
    align: 'center',
    prop: 'status',
    formatter: (row) => {
      return row.status === '1' ? '<el-tag type="success">正常</el-tag>' : '<el-tag type="danger">异常</el-tag>';
    }
  },
  {
    label: '最后更新',
    align: 'center',
    prop: 'lastUpdate',
  },
  {
    label: '描述',
    align: 'center',
    prop: 'description',
  },
  {
    dataType: 'action',
    label: '操作',
    align: 'center',
    fixed: 'right',
    width: 140,
    operation: [
      {
        name: '编辑',
        type: 'text',
        clickFun: (row) => {
          edit(row);
        },
      },
      {
        name: '删除',
        type: 'text',
        clickFun: (row) => {
          deleteRow(row.id);
        },
      },
    ],
  },
];
// 过滤后的数据
const filteredData = computed(() => {
  return mockData.filter(item => {
    const nameMatch = !filters.name || item.name.includes(filters.name);
    const statusMatch = !filters.status || item.status === filters.status;
    const areaMatch = !filters.area || item.area.includes(filters.area);
    return nameMatch && statusMatch && areaMatch;
  });
});
// 获取表格数据
const getTableData = () => {
  pagination.total = filteredData.value.length;
  const start = (pagination.currentPage - 1) * pagination.pageSize;
  const end = start + pagination.pageSize;
  dataList.value = filteredData.value.slice(start, end);
};
// 重置过滤器
const resetFilters = () => {
  filters.name = '';
  filters.status = '';
  filters.area = '';
  pagination.currentPage = 1;
  getTableData();
};
// 分页变化
const changePage = ({ page, limit }) => {
  pagination.currentPage = page;
  pagination.pageSize = limit;
  getTableData();
};
// 多选处理
const handleSelectionChange = (selectionList) => {
  multipleList.value = selectionList;
};
// 新增
const add = () => {
  dialogTitle.value = '新增门禁';
  formData.id = '';
  formData.name = '';
  formData.area = '';
  formData.location = '';
  formData.status = '1';
  formData.description = '';
  dialogVisible.value = true;
};
// 编辑
const edit = (row) => {
  dialogTitle.value = '编辑门禁';
  formData.id = row.id;
  formData.name = row.name;
  formData.area = row.area;
  formData.location = row.location;
  formData.status = row.status;
  formData.description = row.description;
  dialogVisible.value = true;
};
// 保存数据
const saveData = () => {
  if (!formData.name || !formData.area || !formData.location) {
    ElMessage.warning('请填写必填字段');
    return;
  }
  const currentTime = dayjs().format('YYYY-MM-DD HH:mm:ss');
  if (formData.id) {
    // 编辑
    const index = mockData.findIndex(item => item.id === formData.id);
    if (index !== -1) {
      mockData[index] = {
        ...formData,
        lastUpdate: currentTime
      };
      ElMessage.success('编辑成功');
    }
  } else {
    // 新增
    const newId = Math.max(...mockData.map(item => item.id), 0) + 1;
    mockData.unshift({
      ...formData,
      id: newId,
      lastUpdate: currentTime
    });
    ElMessage.success('新增成功');
  }
  dialogVisible.value = false;
  getTableData();
};
// 删除
const deleteRow = (id) => {
  ElMessageBox.confirm('此操作将永久删除该门禁记录, 是否继续?', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning',
  }).then(() => {
    const index = mockData.findIndex(item => item.id === id);
    if (index !== -1) {
      mockData.splice(index, 1);
      ElMessage.success('删除成功');
      getTableData();
    }
  }).catch(() => {});
};
// 批量删除
const batchDelete = () => {
  if (multipleList.value.length === 0) {
    ElMessage.warning('请选择要删除的数据');
    return;
  }
  ElMessageBox.confirm('此操作将永久删除所选门禁记录, 是否继续?', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning',
  }).then(() => {
    const ids = multipleList.value.map(item => item.id);
    mockData.forEach((item, index) => {
      if (ids.includes(item.id)) {
        mockData.splice(index, 1);
      }
    });
    ElMessage.success('删除成功');
    getTableData();
    multipleList.value = [];
  }).catch(() => {});
};
// 初始化数据
onMounted(() => {
  getTableData();
});
</script>
<style>
<style lang="scss" scoped>
.table_list {
  margin-top: unset;
}
.actions {
  display: flex;
  justify-content: space-between;
  margin-bottom: 10px;
}
</style>