Files
pig-farm-controller-fe/src/components/DeviceList.vue
2025-09-19 14:25:20 +08:00

236 lines
6.5 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="device-list">
<el-card>
<template #header>
<div class="card-header">
<span>设备管理</span>
<el-button type="primary" @click="addDevice">添加设备</el-button>
</div>
</template>
<!-- 加载状态 -->
<div v-if="loading" class="loading">
<el-skeleton animated />
</div>
<!-- 错误状态 -->
<div v-else-if="error" class="error">
<el-alert
title="获取设备数据失败"
:description="error"
type="error"
show-icon
closable
@close="error = null"
/>
<el-button type="primary" @click="loadDevices" class="retry-btn">重新加载</el-button>
</div>
<!-- 设备列表 -->
<el-table v-else :data="devices" style="width: 100%">
<el-table-column prop="id" label="设备ID" width="180" />
<el-table-column prop="name" label="设备名称" width="180" />
<el-table-column prop="type" label="设备类型" />
<el-table-column prop="status" label="状态">
<template #default="scope">
<el-tag :type="scope.row.status === 'online' ? 'success' : 'danger'">
{{ scope.row.status === 'online' ? '在线' : '离线' }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="lastUpdate" label="最后更新" />
<el-table-column label="操作">
<template #default="scope">
<el-button size="small" @click="editDevice(scope.row)">编辑</el-button>
<el-button size="small" type="danger" @click="deleteDevice(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
</el-card>
<!-- 添加/编辑设备对话框 -->
<el-dialog v-model="dialogVisible" :title="dialogTitle">
<el-form :model="currentDevice" label-width="120px">
<el-form-item label="设备名称">
<el-input v-model="currentDevice.name" />
</el-form-item>
<el-form-item label="设备类型">
<el-select v-model="currentDevice.type" placeholder="请选择设备类型">
<el-option label="传感器" value="sensor" />
<el-option label="控制器" value="controller" />
<el-option label="摄像头" value="camera" />
</el-select>
</el-form-item>
<el-form-item label="设备状态">
<el-select v-model="currentDevice.status" placeholder="请选择设备状态">
<el-option label="在线" value="online" />
<el-option label="离线" value="offline" />
</el-select>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="saveDevice" :loading="saving">保存</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script>
import deviceService from '../services/deviceService.js';
export default {
name: 'DeviceList',
data() {
return {
devices: [],
loading: false,
error: null,
saving: false,
dialogVisible: false,
dialogTitle: '',
currentDevice: {
id: '',
name: '',
type: '',
status: 'online'
},
isEdit: false
};
},
async mounted() {
await this.loadDevices();
},
methods: {
// 加载设备列表
async loadDevices() {
this.loading = true;
this.error = null;
try {
const data = await deviceService.getDevices();
this.devices = data.map(device => ({
...device,
// 格式化数据显示
type: this.formatDeviceType(device.type),
lastUpdate: device.lastUpdate || '-'
}));
} catch (err) {
this.error = err.message || '未知错误';
console.error('加载设备列表失败:', err);
} finally {
this.loading = false;
}
},
// 格式化设备类型显示
formatDeviceType(type) {
const typeMap = {
'sensor': '传感器',
'controller': '控制器',
'camera': '摄像头'
};
return typeMap[type] || type;
},
addDevice() {
this.dialogTitle = '添加设备';
this.currentDevice = {
id: '',
name: '',
type: '',
status: 'online'
};
this.isEdit = false;
this.dialogVisible = true;
},
editDevice(device) {
this.dialogTitle = '编辑设备';
// 注意这里需要将显示值转换回API值
const typeMap = {
'传感器': 'sensor',
'控制器': 'controller',
'摄像头': 'camera'
};
this.currentDevice = {
...device,
type: typeMap[device.type] || device.type
};
this.isEdit = true;
this.dialogVisible = true;
},
async deleteDevice(device) {
try {
await this.$confirm('确认删除该设备吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
});
await deviceService.deleteDevice(device.id);
this.$message.success('删除成功');
// 重新加载设备列表
await this.loadDevices();
} catch (err) {
if (err !== 'cancel') {
this.$message.error('删除失败: ' + (err.message || '未知错误'));
}
}
},
async saveDevice() {
this.saving = true;
try {
if (this.isEdit) {
// 编辑设备
await deviceService.updateDevice(this.currentDevice.id, this.currentDevice);
this.$message.success('设备更新成功');
} else {
// 添加新设备
await deviceService.createDevice(this.currentDevice);
this.$message.success('设备添加成功');
}
this.dialogVisible = false;
// 重新加载设备列表
await this.loadDevices();
} catch (err) {
this.$message.error('保存失败: ' + (err.message || '未知错误'));
} finally {
this.saving = false;
}
}
}
};
</script>
<style scoped>
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
}
.dialog-footer {
text-align: right;
}
.loading {
padding: 20px 0;
}
.error {
padding: 20px 0;
text-align: center;
}
.retry-btn {
margin-top: 15px;
}
</style>