Phase1_Day4_DeviceManager_page
This commit is contained in:
@@ -0,0 +1,13 @@
|
|||||||
|
import request from '@/uitils/request'
|
||||||
|
|
||||||
|
export function getRegionTree(params) {
|
||||||
|
return request({ url: '/api/DeviceManager/GetRegionTree', method: 'get', params })
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getDevicesByPoint(params) {
|
||||||
|
return request({ url: '/api/DeviceManager/GetDevicesByPoint', method: 'get', params })
|
||||||
|
}
|
||||||
|
|
||||||
|
export function updateDevice(id, data) {
|
||||||
|
return request({ url: `/api/DeviceManager/${id}`, method: 'put', data })
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
<template>
|
||||||
|
<div class="device-table">
|
||||||
|
<div class="toolbar" v-if="selectedPoint">
|
||||||
|
<span>点位: <strong>{{ selectedPoint.name }}</strong></span>
|
||||||
|
<el-button size="small" type="primary" @click="loadDevices">刷新</el-button>
|
||||||
|
</div>
|
||||||
|
<el-table :data="devices" row-key="deviceId" v-loading="loading" stripe max-height="calc(100vh - 240px)">
|
||||||
|
<el-table-column prop="deviceName" label="名称" min-width="150" />
|
||||||
|
<el-table-column prop="deviceCategory" label="种类" width="120" />
|
||||||
|
<el-table-column prop="deviceGroup" label="分组" width="100" />
|
||||||
|
<el-table-column label="状态" width="80">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-tag :type="row.isOnline==='在线'?'success':'danger'" size="small">{{ row.isOnline }}</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="adapterCode" label="来源" width="120" />
|
||||||
|
<el-table-column label="操作" width="120" fixed="right">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-button size="small" text @click="$emit('edit', row)">编辑</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, watch } from 'vue'
|
||||||
|
import { getDevicesByPoint } from '../api/deviceManager'
|
||||||
|
|
||||||
|
const props = defineProps({ selectedPoint: Object })
|
||||||
|
defineEmits(['edit'])
|
||||||
|
const devices = ref([])
|
||||||
|
const loading = ref(false)
|
||||||
|
|
||||||
|
const loadDevices = async () => {
|
||||||
|
if (!props.selectedPoint?.id) return
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
const res = await getDevicesByPoint({ pointId: props.selectedPoint.id, page: 1, size: 100 })
|
||||||
|
devices.value = res.items || []
|
||||||
|
} finally { loading.value = false }
|
||||||
|
}
|
||||||
|
watch(() => props.selectedPoint, loadDevices, { immediate: true })
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.device-table { padding: 8px; }
|
||||||
|
.toolbar { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; }
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
<template>
|
||||||
|
<div class="region-tree">
|
||||||
|
<el-input v-model="filterText" placeholder="搜索区域/点位" size="small" clearable />
|
||||||
|
<el-tree
|
||||||
|
ref="treeRef"
|
||||||
|
:data="treeData"
|
||||||
|
:props="{ children: 'children', label: 'label' }"
|
||||||
|
:filter-node-method="filterNode"
|
||||||
|
node-key="id"
|
||||||
|
highlight-current
|
||||||
|
:expand-on-click-node="true"
|
||||||
|
@node-click="handleNodeClick"
|
||||||
|
style="margin-top:8px; max-height:calc(100vh - 200px); overflow-y:auto"
|
||||||
|
>
|
||||||
|
<template #default="{ data }">
|
||||||
|
<span class="tree-node">
|
||||||
|
<el-icon v-if="data.type==='region'"><Folder /></el-icon>
|
||||||
|
<el-icon v-else><Location /></el-icon>
|
||||||
|
<span>{{ data.label }}</span>
|
||||||
|
<el-tag size="small" type="info" style="margin-left:6px">{{ data.deviceCount || 0 }}</el-tag>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-tree>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, watch } from 'vue'
|
||||||
|
import { getRegionTree } from '../api/deviceManager'
|
||||||
|
|
||||||
|
const emit = defineEmits(['select-point'])
|
||||||
|
const treeRef = ref(null)
|
||||||
|
const treeData = ref([])
|
||||||
|
const filterText = ref('')
|
||||||
|
|
||||||
|
const loadTree = async () => {
|
||||||
|
const res = await getRegionTree()
|
||||||
|
treeData.value = res || []
|
||||||
|
}
|
||||||
|
loadTree()
|
||||||
|
|
||||||
|
const filterNode = (value, data) => {
|
||||||
|
if (!value) return true
|
||||||
|
return data.label.includes(value)
|
||||||
|
}
|
||||||
|
watch(filterText, (val) => {
|
||||||
|
treeRef.value?.filter(val)
|
||||||
|
})
|
||||||
|
|
||||||
|
const handleNodeClick = (data) => {
|
||||||
|
if (data.type === 'point') {
|
||||||
|
const id = parseInt(data.id.replace('p_', ''))
|
||||||
|
emit('select-point', { id, name: data.label })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.region-tree { padding: 8px; }
|
||||||
|
.tree-node { display: flex; align-items: center; gap: 4px; }
|
||||||
|
</style>
|
||||||
43
web.vite/src/views/warehouse/DeviceManager/index.vue
Normal file
43
web.vite/src/views/warehouse/DeviceManager/index.vue
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
<template>
|
||||||
|
<div class="device-manager-page">
|
||||||
|
<div class="left-panel">
|
||||||
|
<RegionTree @select-point="onSelectPoint" />
|
||||||
|
</div>
|
||||||
|
<div class="right-panel">
|
||||||
|
<DeviceTable :selectedPoint="selectedPoint" @edit="onEdit" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import RegionTree from './components/RegionTree.vue'
|
||||||
|
import DeviceTable from './components/DeviceTable.vue'
|
||||||
|
|
||||||
|
const selectedPoint = ref(null)
|
||||||
|
|
||||||
|
const onSelectPoint = (point) => {
|
||||||
|
selectedPoint.value = point
|
||||||
|
}
|
||||||
|
|
||||||
|
const onEdit = (device) => {
|
||||||
|
// TODO: open edit dialog (Day 5)
|
||||||
|
console.log('edit', device)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.device-manager-page {
|
||||||
|
display: flex;
|
||||||
|
height: calc(100vh - 80px);
|
||||||
|
}
|
||||||
|
.left-panel {
|
||||||
|
width: 280px;
|
||||||
|
border-right: 1px solid #e4e7ed;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
.right-panel {
|
||||||
|
flex: 1;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user