Files
dyf-vue-ui/src/views/controlCenter/controlPanel/index.vue
2025-08-26 18:45:15 +08:00

318 lines
12 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="p-2">
<el-row :gutter="20">
<!-- 部门树 -->
<el-col :lg="4" :xs="24" style="" class="main-tree">
<el-input v-model="deptName" placeholder="输入分组名称" prefix-icon="Search" clearable />
<el-tree ref="deptTreeRef" class="mt-2" node-key="id" :data="deptOptions"
:props="{ label: 'groupName', children: 'children' }" :expand-on-click-node="false"
:filter-node-method="filterNode" highlight-current default-expand-all @node-click="handleNodeClick"></el-tree>
</el-col>
<el-col :lg="20" :xs="24">
<transition :enter-active-class="proxy?.animate.searchAnimate.enter"
:leave-active-class="proxy?.animate.searchAnimate.leave">
<div v-show="showSearch" class="mb-[10px]">
<el-card>
<!-- =========搜索按钮操作======= -->
<div class="btn_search">
<el-button :type="isListView ? 'primary' : ''" @click="switchView('list')">
{{ isListView ? '列表显示' : '列表显示' }}
</el-button>
<el-button :type="!isListView ? 'primary' : ''" @click="switchView('map')">
{{ !isListView ? '地图显示' : '地图显示' }}
</el-button>
<el-button type="primary" plain>发送消息</el-button>
<el-button type="primary" plain>电子围栏</el-button>
<el-button type="danger" plain>强制报警</el-button>
<div style="position: absolute; right:30px; top:20px">
<el-input v-model="queryParams.deviceMac" placeholder="MAC/IMEI" clearable
style="width: 200px; margin-right: 20px;" />
<el-button type="primary" plain @click="toggleFilter">高级筛选</el-button>
</div>
</div>
<el-collapse accordion v-model="activeNames">
<el-collapse-item name="1">
<el-form ref="queryFormRef" :model="queryParams" :inline="true" class="queryFormRef">
<el-form-item label="设备类型" prop="deviceType">
<el-select v-model="queryParams.deviceType" placeholder="设备类型">
<el-option v-for="item in deviceTypeOptions" :key="item.value" :label="item.typeName"
:value="item.id" />
</el-select>
</el-form-item>
<el-form-item label="设备名称" prop="deviceName">
<el-input v-model="queryParams.deviceName" placeholder="请输入设备名称" clearable />
</el-form-item>
<el-form-item label="设备状态" prop="deviceStatus">
<el-select v-model="queryParams.deviceStatus" placeholder="设备状态" clearable>
<el-option label="在线" value="1"></el-option>
<el-option label="离线" value="0"></el-option>
</el-select>
</el-form-item>
<el-form-item label="设备MAC" prop="deviceMac">
<el-input v-model="queryParams.deviceMac" placeholder="请输入设备MAC" clearable />
</el-form-item>
<el-form-item label="设备IMEI" prop="deviceImei">
<el-input v-model="queryParams.deviceImei" placeholder="请输入设备IMEI" clearable
@keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="使用人员" prop="currentOwnerId">
<el-input v-model="queryParams.currentOwnerId" placeholder="请输入使用人员姓名" clearable
@keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="通信方式" prop="communicationMode">
<el-select v-model="queryParams.communicationMode" placeholder="请选择通信方式" clearable>
<el-option label="4G" value="0"></el-option>
<el-option label="蓝牙" value="1"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleQuery">查询</el-button>
<el-button @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
</el-collapse-item>
</el-collapse>
</el-card>
</div>
</transition>
<el-card class="Maplist">
<div v-if="isListView" key="list">
<el-table v-loading="loading" border :data="deviceList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="50" align="center" />
<el-table-column label="设备名称" align="center" prop="deviceName" />
<el-table-column label="设备图片" align="center" prop="devicePic">
<template #default="scope">
<el-popover placement="right" trigger="click">
<template #reference>
<img :src="scope.row.devicePic"
style="width: 40px; height: 40px; cursor: pointer; object-fit: contain"
class="hover:opacity-80 transition-opacity" />
</template>
<img :src="scope.row.devicePic" style="max-width: 600px; max-height: 600px; object-fit: contain" />
</el-popover>
</template>
</el-table-column>
<el-table-column label="设备类型" align="center" prop="typeName" />
<el-table-column label="使用人员" align="center" prop="personnelBy" />
<el-table-column label="电量" align="center" prop="battery" />
<el-table-column label="设备状态" align="center" prop="onlineStatus">
<template #default="scope">
<div class="normal green" v-if="scope.row.onlineStatus == 1">在线</div>
<div class="normal red" v-if="scope.row.onlineStatus == 0">离线</div>
</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="180" class-name="small-padding fixed-width">
<template #default="scope">
<el-button link type="primary" @click="handleControl(scope.row)">控制面板</el-button>
</template>
</el-table-column>
</el-table>
<pagination v-show="total > 0" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize"
:total="total" @pagination="getList" />
</div>
<div v-else key="map" v-if="deviceList.length > 0">
<Amap :deviceList="deviceList"></Amap>
</div>
</el-card>
</el-col>
</el-row>
</div>
</template>
<script setup name="User" lang="ts">
import api from '@/api/controlCenter/controlPanel/index'
import apiTypeAll from '@/api/equipmentManagement/device/index';
import { deviceQuery, deviceVO } from '@/api/controlCenter/controlPanel/types';
import Amap from "./components/map.vue";
import { UserVO } from '@/api/system/user/types';
const router = useRouter();
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { sys_normal_disable } = toRefs<any>(proxy?.useDict('sys_normal_disable', 'sys_user_sex'));
const deviceList = ref<deviceVO[]>();
const loading = ref(true);
const showSearch = ref(true);
const ids = ref<Array<number | string>>([]);
const single = ref(true);
const multiple = ref(true);
const total = ref(0);
const deptName = ref();
const deptOptions = ref([])
const deptTreeRef = ref<ElTreeInstance>();
const queryFormRef = ref<ElFormInstance>();
const userFormRef = ref<ElFormInstance>();
const isListView = ref(true);
const activeNames = ref([]);
const deviceTypeOptions = ref([]); //设备类型
const enabledDeptOptions = ref();
const initData: PageData<'', deviceQuery> = {
queryParams: {
pageNum: 1,
pageSize: 10,
deviceId: '',
deviceName: '',
deviceStatus: '',
deviceMac: '',
deviceImei: '',
currentOwnerId: '',
communicationMode: '',
groupId: '',
deviceType: ''
},
rules: undefined,
form: ''
};
const data = reactive<PageData<'', deviceQuery>>(initData);
const { queryParams } = toRefs<PageData<'', deviceQuery>>(data);
const switchView = (view) => {
isListView.value = (view === 'list');
};
/** 通过条件过滤节点 */
const filterNode = (value: string, data: any) => {
if (!value) return true;
return data.groupName.indexOf(value) !== -1;
};
// 设备类型
const getDeviceType = () => {
apiTypeAll.deviceTypeAll().then(res => {
if (res.code == 200) {
deviceTypeOptions.value = res.data
}
}).catch(err => {
})
};
/** 根据名称筛选部门树 */
watchEffect(
() => {
deptTreeRef.value?.filter(deptName.value);
},
{
flush: 'post' // watchEffect会在DOM挂载或者更新之前就会触发此属性控制在DOM元素更新后运行
}
);
const toggleFilter = () => {
if (activeNames.value.length > 0) {
activeNames.value = [];
} else {
activeNames.value = ['1'];
}
};
/** 查询用户列表 */
const getList = async () => {
loading.value = false;
const res = await api.deviceControlCenterList(queryParams.value);
loading.value = false;
deviceList.value = res.rows;
total.value = res.total;
};
/** 查询部门下拉树结构 */
const getDeptTree = async () => {
const res = await api.devicegroupList('');
deptOptions.value = res.data;
enabledDeptOptions.value = filterDisabledDept(res.data);
};
/** 过滤禁用的部门 */
const filterDisabledDept = (deptList: any[]) => {
return deptList.filter((dept) => {
if (dept.disabled) {
return false;
}
if (dept.children && dept.children.length) {
dept.children = filterDisabledDept(dept.children);
}
return true;
});
};
/** 节点单击事件 */
const handleNodeClick = (data: any) => {
queryParams.value.groupId = data.id;
handleQuery();
};
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.value.pageNum = 1;
getList();
};
/** 重置按钮操作 */
const resetQuery = () => {
queryFormRef.value?.resetFields();
queryParams.value.pageNum = 1;
queryParams.value.groupId = undefined;
deptTreeRef.value?.setCurrentKey(undefined);
handleQuery();
};
/** 设备控制跳转 */
const handleControl = (row: any) => {
const deviceId = row.id;
router.push('/controlCenter/6170/' + deviceId);
};
/** 选择条数 */
const handleSelectionChange = (selection: UserVO[]) => {
ids.value = selection.map((item: any) => item.id);
single.value = selection.length != 1;
multiple.value = !selection.length;
};
/** 重置操作表单 */
const reset = () => {
userFormRef.value?.resetFields();
};
onMounted(() => {
getDeptTree(); // 初始化部门数据
getList(); // 初始化列表数据
getDeviceType() //设备类型
});
</script>
<style lang="scss" scoped>
:deep .el-collapse-item__header {
display: none;
}
.main-tree {
border-radius: 4px;
box-shadow: 0px 0px 6px 0px rgba(0, 34, 96, 0.1);
background: rgba(255, 255, 255, 1);
width: 212px;
border: none;
padding-top: 10px;
}
.el-card {
border: none
}
.btn_search {
padding: 0px 15px 15px 0px;
// border-bottom: 1px solid rgba(235, 238, 248, 1);
}
.queryFormRef {
margin-top: 20px;
}
.green {
color: rgba(0, 165, 82, 1);
}
.red {
color: rgba(224, 52, 52, 1);
}
.Maplist {
height: 680px;
overflow: auto;
}
</style>