根据后端新接口重构设备管理界面
This commit is contained in:
		| @@ -1,7 +1,57 @@ | ||||
| import http from '../utils/http.js'; | ||||
|  | ||||
| /** | ||||
|  * 设备管理API | ||||
|  * 区域主控管理API | ||||
|  */ | ||||
| export class AreaControllerApi { | ||||
|   /** | ||||
|    * 获取区域主控列表 | ||||
|    * @returns {Promise} 区域主控列表 | ||||
|    */ | ||||
|   static list() { | ||||
|     return http.get('/api/v1/area-controllers'); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * 创建新区域主控 | ||||
|    * @param {Object} areaControllerData 区域主控数据 | ||||
|    * @returns {Promise} 创建结果 | ||||
|    */ | ||||
|   static create(areaControllerData) { | ||||
|     return http.post('/api/v1/area-controllers', areaControllerData); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * 获取区域主控详情 | ||||
|    * @param {string|number} id 区域主控ID | ||||
|    * @returns {Promise} 区域主控详情 | ||||
|    */ | ||||
|   static get(id) { | ||||
|     return http.get(`/api/v1/area-controllers/${id}`); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * 更新区域主控信息 | ||||
|    * @param {string|number} id 区域主控ID | ||||
|    * @param {Object} areaControllerData 区域主控数据 | ||||
|    * @returns {Promise} 更新结果 | ||||
|    */ | ||||
|   static update(id, areaControllerData) { | ||||
|     return http.put(`/api/v1/area-controllers/${id}`, areaControllerData); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * 删除区域主控 | ||||
|    * @param {string|number} id 区域主控ID | ||||
|    * @returns {Promise} 删除结果 | ||||
|    */ | ||||
|   static delete(id) { | ||||
|     return http.delete(`/api/v1/area-controllers/${id}`); | ||||
|   } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * 普通设备管理API | ||||
|  */ | ||||
| export class DeviceApi { | ||||
|   /** | ||||
| @@ -49,5 +99,3 @@ export class DeviceApi { | ||||
|     return http.delete(`/api/v1/devices/${id}`); | ||||
|   } | ||||
| } | ||||
|  | ||||
| export default DeviceApi; | ||||
| @@ -1,4 +1,4 @@ | ||||
| import DeviceApi from './device.js'; | ||||
| import { AreaControllerApi, DeviceApi } from './device.js'; | ||||
| import PlanApi from './plan.js'; | ||||
| import UserApi from './user.js'; | ||||
|  | ||||
| @@ -7,6 +7,7 @@ import UserApi from './user.js'; | ||||
|  */ | ||||
| export class ApiClient { | ||||
|   constructor() { | ||||
|     this.areaControllers = AreaControllerApi; | ||||
|     this.devices = DeviceApi; | ||||
|     this.plans = PlanApi; | ||||
|     this.users = UserApi; | ||||
|   | ||||
| @@ -14,32 +14,32 @@ | ||||
|       @submit.prevent | ||||
|     > | ||||
|       <!-- 基础信息 --> | ||||
|       <el-form-item label="设备名" prop="name"> | ||||
|       <el-form-item label="名称" prop="name"> | ||||
|         <el-input v-model="formData.name" /> | ||||
|       </el-form-item> | ||||
|        | ||||
|       <el-form-item label="设备类型" prop="type"> | ||||
|         <el-select v-model="formData.type" @change="handleTypeChange"> | ||||
|       <el-form-item label="类型" prop="type"> | ||||
|         <el-select v-model="formData.type" @change="handleTypeChange" :disabled="isEdit"> | ||||
|           <el-option label="区域主控" value="area_controller" /> | ||||
|           <el-option label="普通设备" value="device" /> | ||||
|         </el-select> | ||||
|       </el-form-item> | ||||
|        | ||||
|       <el-form-item label="设备位置描述" prop="location"> | ||||
|       <el-form-item label="位置描述" prop="location"> | ||||
|         <el-input v-model="formData.location" type="textarea" /> | ||||
|       </el-form-item> | ||||
|        | ||||
|       <!-- 区域主控类型额外字段 --> | ||||
|       <div v-if="formData.type === 'area_controller'"> | ||||
|         <el-form-item label="LoRa地址" prop="loraAddress"> | ||||
|           <el-input v-model="formData.loraAddress" /> | ||||
|         <el-form-item label="网络ID" prop="network_id"> | ||||
|           <el-input v-model="formData.network_id" /> | ||||
|         </el-form-item> | ||||
|       </div> | ||||
|        | ||||
|       <!-- 普通设备类型额外字段 --> | ||||
|       <div v-if="formData.type === 'device'"> | ||||
|         <el-form-item label="区域主控" prop="parentControllerId"> | ||||
|           <el-select v-model="formData.parentControllerId" placeholder="请选择区域主控"> | ||||
|         <el-form-item label="所属区域主控" prop="area_controller_id"> | ||||
|           <el-select v-model="formData.area_controller_id" placeholder="请选择区域主控"> | ||||
|             <el-option | ||||
|               v-for="controller in areaControllers" | ||||
|               :key="controller.id" | ||||
| @@ -49,38 +49,39 @@ | ||||
|           </el-select> | ||||
|         </el-form-item> | ||||
|          | ||||
|         <el-form-item label="设备种类" prop="subType"> | ||||
|           <el-select v-model="formData.subType" placeholder="请选择设备种类"> | ||||
|             <el-option label="风扇" value="fan" /> | ||||
|             <el-option label="温度传感器" value="temperature" /> | ||||
|             <el-option label="湿度传感器" value="humidity" /> | ||||
|             <el-option label="氨气传感器" value="ammonia" /> | ||||
|             <el-option label="饲料阀门" value="feed_valve" /> | ||||
|             <el-option label="水帘" value="water_curtain" /> | ||||
|         <el-form-item label="设备模板" prop="device_template_id"> | ||||
|           <el-select v-model="formData.device_template_id" placeholder="请选择设备模板"> | ||||
|             <!-- 假设设备模板列表从API获取或硬编码 --> | ||||
|             <el-option label="温度传感器" :value="1" /> | ||||
|             <el-option label="湿度传感器" :value="2" /> | ||||
|             <el-option label="氨气传感器" :value="3" /> | ||||
|             <el-option label="饲料阀门" :value="4" /> | ||||
|             <el-option label="风扇" :value="5" /> | ||||
|             <el-option label="水帘" :value="6" /> | ||||
|           </el-select> | ||||
|         </el-form-item> | ||||
|          | ||||
|         <el-form-item label="485总线号" prop="busNumber"> | ||||
|         <el-form-item label="485总线号" prop="properties.bus_number"> | ||||
|           <el-input-number  | ||||
|             v-model="formData.busNumber"  | ||||
|             v-model="formData.properties.bus_number"  | ||||
|             :min="0" | ||||
|             controls-position="right" | ||||
|             style="width: 100%" | ||||
|           /> | ||||
|         </el-form-item> | ||||
|          | ||||
|         <el-form-item label="485总线地址" prop="busAddress"> | ||||
|         <el-form-item label="485总线地址" prop="properties.bus_address"> | ||||
|           <el-input-number  | ||||
|             v-model="formData.busAddress"  | ||||
|             v-model="formData.properties.bus_address"  | ||||
|             :min="0" | ||||
|             controls-position="right" | ||||
|             style="width: 100%" | ||||
|           /> | ||||
|         </el-form-item> | ||||
|          | ||||
|         <el-form-item label="继电器通道号" prop="relayChannel"> | ||||
|         <el-form-item label="继电器通道号" prop="properties.relay_channel"> | ||||
|           <el-input-number  | ||||
|             v-model="formData.relayChannel"  | ||||
|             v-model="formData.properties.relay_channel"  | ||||
|             :min="0" | ||||
|             controls-position="right" | ||||
|             style="width: 100%" | ||||
| @@ -99,9 +100,9 @@ | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import { ref, reactive, onMounted, watch, computed } from 'vue'; | ||||
| import { ref, reactive, onMounted, watch, computed, nextTick } from 'vue'; | ||||
| import { ElMessage } from 'element-plus'; | ||||
| import { DeviceApi } from '../api/device.js'; | ||||
| import { AreaControllerApi, DeviceApi } from '../api/device.js'; | ||||
|  | ||||
| export default { | ||||
|   name: 'DeviceForm', | ||||
| @@ -121,121 +122,146 @@ export default { | ||||
|   }, | ||||
|   emits: ['update:visible', 'success', 'cancel'], | ||||
|   setup(props, { emit }) { | ||||
|     // 表单引用 | ||||
|     const formRef = ref(null); | ||||
|      | ||||
|     // 加载状态 | ||||
|     const loading = ref(false); | ||||
|      | ||||
|     // 区域主控列表 | ||||
|     const areaControllers = ref([]); | ||||
|      | ||||
|     // 表单数据 | ||||
|     const formData = reactive({ | ||||
|     const initialFormData = () => ({ | ||||
|       id: '', | ||||
|       name: '', | ||||
|       type: '', | ||||
|       type: 'device', // 默认创建普通设备 | ||||
|       location: '', | ||||
|       // 区域主控字段 | ||||
|       loraAddress: '', | ||||
|       // 普通设备字段 | ||||
|       parentControllerId: '', | ||||
|       subType: '', | ||||
|       busNumber: 0, | ||||
|       busAddress: 0, | ||||
|       relayChannel: 0 | ||||
|       network_id: '', // 区域主控字段 | ||||
|       area_controller_id: '', // 普通设备字段 | ||||
|       device_template_id: '', // 普通设备字段 | ||||
|       properties: { // 嵌套的properties对象 | ||||
|         bus_number: 0, | ||||
|         bus_address: 0, | ||||
|         relay_channel: 0, | ||||
|       } | ||||
|     }); | ||||
|  | ||||
|     const formData = reactive(initialFormData()); | ||||
|      | ||||
|     // 表单验证规则 | ||||
|     const rules = { | ||||
|     const rules = computed(() => ({ | ||||
|       name: [ | ||||
|         { required: true, message: '请输入设备名', trigger: 'blur' } | ||||
|         { required: true, message: '请输入名称', trigger: 'blur' } | ||||
|       ], | ||||
|       type: [ | ||||
|         { required: true, message: '请选择设备类型', trigger: 'change' } | ||||
|         { required: true, message: '请选择类型', trigger: 'change' } | ||||
|       ], | ||||
|       location: [ | ||||
|         { required: true, message: '请输入设备位置描述', trigger: 'blur' } | ||||
|         { required: true, message: '请输入位置描述', trigger: 'blur' } | ||||
|       ], | ||||
|       loraAddress: [ | ||||
|         { required: true, message: '请输入LoRa地址', trigger: 'blur' } | ||||
|       network_id: [ | ||||
|         { required: formData.type === 'area_controller', message: '请输入网络ID', trigger: 'blur' } | ||||
|       ], | ||||
|       parentControllerId: [ | ||||
|         { required: true, message: '请选择区域主控', trigger: 'change' } | ||||
|       area_controller_id: [ | ||||
|         { required: formData.type === 'device', message: '请选择所属区域主控', trigger: 'change' } | ||||
|       ], | ||||
|       subType: [ | ||||
|         { required: true, message: '请选择设备种类', trigger: 'change' } | ||||
|       device_template_id: [ | ||||
|         { required: formData.type === 'device', message: '请选择设备模板', trigger: 'change' } | ||||
|       ], | ||||
|       busNumber: [ | ||||
|         { required: true, message: '请输入485总线号', trigger: 'blur' } | ||||
|       'properties.bus_number': [ | ||||
|         { required: formData.type === 'device', message: '请输入485总线号', trigger: 'blur' } | ||||
|       ], | ||||
|       busAddress: [ | ||||
|         { required: true, message: '请输入485总线地址', trigger: 'blur' } | ||||
|       'properties.bus_address': [ | ||||
|         { required: formData.type === 'device', message: '请输入485总线地址', trigger: 'blur' } | ||||
|       ], | ||||
|       relayChannel: [ | ||||
|         { required: true, message: '请输入继电器通道号', trigger: 'blur' } | ||||
|       'properties.relay_channel': [ | ||||
|         { required: formData.type === 'device', message: '请输入继电器通道号', trigger: 'blur' } | ||||
|       ] | ||||
|     }; | ||||
|     })); | ||||
|      | ||||
|     // 标题计算 | ||||
|     const title = computed(() => { | ||||
|       return props.isEdit ? '编辑设备' : '添加设备'; | ||||
|     }); | ||||
|      | ||||
|     // 处理类型切换 | ||||
|     const handleTypeChange = (value) => { | ||||
|       // 清除之前的数据 | ||||
|       // 清除不同类型特有的字段 | ||||
|       if (value === 'area_controller') { | ||||
|         // 清除普通设备字段 | ||||
|         formData.parentControllerId = ''; | ||||
|         formData.subType = ''; | ||||
|         formData.busNumber = 0; | ||||
|         formData.busAddress = 0; | ||||
|         formData.relayChannel = 0; | ||||
|         formData.area_controller_id = ''; | ||||
|         formData.device_template_id = ''; | ||||
|         formData.properties = { bus_number: 0, bus_address: 0, relay_channel: 0 }; | ||||
|       } else { | ||||
|         // 清除区域主控字段 | ||||
|         formData.loraAddress = ''; | ||||
|         formData.network_id = ''; | ||||
|       } | ||||
|       // 触发验证规则更新 | ||||
|       nextTick(() => { | ||||
|         formRef.value.clearValidate(); | ||||
|       }); | ||||
|     }; | ||||
|      | ||||
|     // 获取区域主控列表 | ||||
|     const loadAreaControllers = async () => { | ||||
|       try { | ||||
|         const response = await DeviceApi.list(); | ||||
|         // 筛选出类型为区域主控的设备 | ||||
|         areaControllers.value = response.data.filter(device => device.type === 'area_controller'); | ||||
|         const response = await AreaControllerApi.list(); | ||||
|         areaControllers.value = response.data || []; | ||||
|       } catch (error) { | ||||
|         console.error('获取区域主控列表失败:', error); | ||||
|         areaControllers.value = []; | ||||
|       } | ||||
|     }; | ||||
|      | ||||
|     // 关闭对话框 | ||||
|     const handleClose = () => { | ||||
|       emit('update:visible', false); | ||||
|       emit('cancel'); | ||||
|       // 重置表单 | ||||
|       Object.assign(formData, initialFormData()); | ||||
|       formRef.value.resetFields(); | ||||
|     }; | ||||
|      | ||||
|     const getSubmitData = () => { | ||||
|       const data = { | ||||
|         name: formData.name, | ||||
|         location: formData.location, | ||||
|         properties: formData.properties // properties直接作为对象传递 | ||||
|       }; | ||||
|  | ||||
|       if (formData.type === 'area_controller') { | ||||
|         data.network_id = formData.network_id; | ||||
|       } else { | ||||
|         data.area_controller_id = formData.area_controller_id; | ||||
|         data.device_template_id = formData.device_template_id; | ||||
|       } | ||||
|       return data; | ||||
|     }; | ||||
|      | ||||
|     // 提交表单 | ||||
|     const handleSubmit = async () => { | ||||
|       await formRef.value.validate(async (valid) => { | ||||
|         if (valid) { | ||||
|           loading.value = true; | ||||
|           try { | ||||
|             let result; | ||||
|             const submitData = getSubmitData(); | ||||
|  | ||||
|             if (props.isEdit) { | ||||
|               // 编辑设备 | ||||
|               result = await DeviceApi.update(formData.id, getSubmitData()); | ||||
|               if (formData.type === 'area_controller') { | ||||
|                 result = await AreaControllerApi.update(formData.id, submitData); | ||||
|               } else { | ||||
|                 result = await DeviceApi.update(formData.id, submitData); | ||||
|               } | ||||
|             } else { | ||||
|               // 创建设备 | ||||
|               result = await DeviceApi.create(getSubmitData()); | ||||
|               if (formData.type === 'area_controller') { | ||||
|                 result = await AreaControllerApi.create(submitData); | ||||
|               } else { | ||||
|                 result = await DeviceApi.create(submitData); | ||||
|               } | ||||
|             } | ||||
|              | ||||
|             emit('success', result); | ||||
|             // 适配DeviceList的树形结构,添加type和parent_id | ||||
|             const processedResult = { | ||||
|               ...result.data, | ||||
|               type: formData.type | ||||
|             }; | ||||
|             if (formData.type === 'device') { | ||||
|               processedResult.parent_id = processedResult.area_controller_id; | ||||
|             } | ||||
|  | ||||
|             emit('success', processedResult); | ||||
|             handleClose(); | ||||
|           } catch (error) { | ||||
|             console.error('保存设备失败:', error); | ||||
|             ElMessage.error(props.isEdit ? '编辑设备失败' : '创建设备失败'); | ||||
|             ElMessage.error(props.isEdit ? '编辑设备失败: ' + (error.message || '未知错误') : '创建设备失败: ' + (error.message || '未知错误')); | ||||
|           } finally { | ||||
|             loading.value = false; | ||||
|           } | ||||
| @@ -243,83 +269,54 @@ export default { | ||||
|       }); | ||||
|     }; | ||||
|      | ||||
|     // 获取提交数据 | ||||
|     const getSubmitData = () => { | ||||
|       const data = { | ||||
|         name: formData.name, | ||||
|         type: formData.type, | ||||
|         location: formData.location | ||||
|       }; | ||||
|        | ||||
|       // 添加properties字段,作为JSON对象传递 | ||||
|       const properties = {}; | ||||
|        | ||||
|       if (formData.type === 'area_controller') { | ||||
|         properties.lora_address = formData.loraAddress; | ||||
|       } else if (formData.type === 'device') { | ||||
|         properties.bus_number = formData.busNumber; | ||||
|         properties.bus_address = formData.busAddress; | ||||
|         properties.relay_channel = formData.relayChannel; | ||||
|         data.parent_id = formData.parentControllerId; | ||||
|         data.sub_type = formData.subType; | ||||
|       } | ||||
|        | ||||
|       // 直接使用properties对象,不进行序列化 | ||||
|       data.properties = properties; | ||||
|        | ||||
|       return data; | ||||
|     }; | ||||
|      | ||||
|     // 监听设备数据变化 | ||||
|     watch(() => props.deviceData, (newVal) => { | ||||
|       if (newVal && Object.keys(newVal).length > 0) { | ||||
|         // 填充表单数据 | ||||
|         Object.keys(formData).forEach(key => { | ||||
|           // 处理字段名映射 | ||||
|           let dataKey = key; | ||||
|           if (key === 'parentControllerId') { | ||||
|             dataKey = 'parent_id'; | ||||
|           } else if (key === 'subType') { | ||||
|             dataKey = 'sub_type'; | ||||
|           } | ||||
|            | ||||
|           if (newVal[dataKey] !== undefined) { | ||||
|             formData[key] = newVal[dataKey]; | ||||
|           } | ||||
|         // 重置表单以清除旧数据和验证状态 | ||||
|         Object.assign(formData, initialFormData()); | ||||
|         nextTick(() => { | ||||
|           formRef.value.clearValidate(); | ||||
|         }); | ||||
|          | ||||
|  | ||||
|         formData.id = newVal.id; | ||||
|         formData.name = newVal.name; | ||||
|         formData.type = newVal.type; | ||||
|         formData.location = newVal.location; | ||||
|  | ||||
|         if (newVal.type === 'area_controller') { | ||||
|           formData.network_id = newVal.network_id || ''; | ||||
|         } else if (newVal.type === 'device') { | ||||
|           formData.area_controller_id = newVal.area_controller_id || newVal.parent_id || ''; | ||||
|           formData.device_template_id = newVal.device_template_id || ''; | ||||
|         } | ||||
|  | ||||
|         // 处理properties对象的数据填充 | ||||
|         if (newVal.properties) { | ||||
|           const props = typeof newVal.properties === 'string' ? JSON.parse(newVal.properties) : newVal.properties; | ||||
|           if (formData.type === 'area_controller') { | ||||
|             formData.loraAddress = props.lora_address || ''; | ||||
|           } else if (formData.type === 'device') { | ||||
|             formData.busNumber = props.bus_number || 0; | ||||
|             formData.busAddress = props.bus_address || 0; | ||||
|             formData.relayChannel = props.relay_channel || 0; | ||||
|           } | ||||
|           // 确保properties是一个对象,如果API返回的是字符串则尝试解析 | ||||
|           const propsData = typeof newVal.properties === 'string' ? JSON.parse(newVal.properties) : newVal.properties; | ||||
|           Object.assign(formData.properties, propsData); | ||||
|         } | ||||
|       } else { | ||||
|         // 重置表单数据 | ||||
|         Object.keys(formData).forEach(key => { | ||||
|           if (key === 'busNumber' || key === 'busAddress' || key === 'relayChannel') { | ||||
|             formData[key] = 0; | ||||
|           } else { | ||||
|             formData[key] = ''; | ||||
|           } | ||||
|         // 如果没有传入deviceData,则重置为初始状态 | ||||
|         Object.assign(formData, initialFormData()); | ||||
|         nextTick(() => { | ||||
|           formRef.value.clearValidate(); | ||||
|         }); | ||||
|       } | ||||
|     }, { immediate: true }); | ||||
|      | ||||
|     // 监听visible属性变化,当对话框打开时重新加载区域主控列表 | ||||
|     watch(() => props.visible, (newVal) => { | ||||
|       if (newVal) { | ||||
|         // 对话框打开时重新加载区域主控列表 | ||||
|         loadAreaControllers(); | ||||
|         // 如果是新增,确保type是默认值,且清空所有字段 | ||||
|         if (!props.isEdit) { | ||||
|           Object.assign(formData, initialFormData()); | ||||
|           nextTick(() => { | ||||
|             formRef.value.clearValidate(); | ||||
|           }); | ||||
|         } | ||||
|       } | ||||
|     }, { immediate: true }); | ||||
|      | ||||
|     // 组件挂载时加载区域主控列表 | ||||
|     onMounted(() => { | ||||
|       loadAreaControllers(); | ||||
|     }); | ||||
|   | ||||
| @@ -46,19 +46,19 @@ | ||||
|         :scrollbar-always-on="true" | ||||
|         @sort-change="handleSortChange"> | ||||
|         <el-table-column width="40"></el-table-column> | ||||
|         <el-table-column prop="id" label="设备ID" min-width="100" sortable="custom" /> | ||||
|         <el-table-column prop="name" label="设备名称" min-width="120" sortable="custom" /> | ||||
|         <el-table-column prop="type" label="设备类型" min-width="100"> | ||||
|         <el-table-column prop="id" label="ID" min-width="100" sortable="custom" /> | ||||
|         <el-table-column prop="name" label="名称" min-width="120" sortable="custom" /> | ||||
|         <el-table-column prop="type" label="类型" min-width="100"> | ||||
|           <template #default="scope"> | ||||
|             {{ formatDeviceType(scope.row.type) }} | ||||
|           </template> | ||||
|         </el-table-column> | ||||
|         <el-table-column prop="sub_type" label="设备子类型" min-width="100"> | ||||
|         <el-table-column prop="device_template_name" label="设备模板" min-width="120"> | ||||
|           <template #default="scope"> | ||||
|             {{ formatDeviceSubType(scope.row.sub_type) }} | ||||
|             {{ scope.row.type === 'device' ? scope.row.device_template_name || '-' : '-' }} | ||||
|           </template> | ||||
|         </el-table-column> | ||||
|         <el-table-column prop="location" label="设备地址描述" min-width="150" /> | ||||
|         <el-table-column prop="location" label="地址描述" min-width="150" /> | ||||
|         <el-table-column label="操作" min-width="120" align="center"> | ||||
|           <template #default="scope"> | ||||
|             <el-button size="small" @click="editDevice(scope.row)">编辑</el-button> | ||||
| @@ -177,22 +177,9 @@ export default { | ||||
|       return typeMap[type] || type || '-'; | ||||
|     }, | ||||
|      | ||||
|     // 格式化设备子类型显示 | ||||
|     formatDeviceSubType(subType) { | ||||
|       const subTypeMap = { | ||||
|         '': '-', | ||||
|         'temperature': '温度传感器', | ||||
|         'humidity': '湿度传感器', | ||||
|         'ammonia': '氨气传感器', | ||||
|         'feed_valve': '饲料阀门', | ||||
|         'fan': '风扇', | ||||
|         'water_curtain': '水帘' | ||||
|       }; | ||||
|       return subTypeMap[subType] || subType || '-'; | ||||
|     }, | ||||
|      | ||||
|     addDevice() { | ||||
|       this.currentDevice = {}; | ||||
|       // 默认添加普通设备,如果需要添加区域主控,可以在DeviceForm中选择或通过其他入口触发 | ||||
|       this.currentDevice = { type: 'device' };  | ||||
|       this.isEdit = false; | ||||
|       this.dialogVisible = true; | ||||
|     }, | ||||
| @@ -222,7 +209,7 @@ export default { | ||||
|           type: 'warning' | ||||
|         }); | ||||
|          | ||||
|         await deviceService.deleteDevice(device.id); | ||||
|         await deviceService.deleteDevice(device); | ||||
|         this.$message.success('删除成功'); | ||||
|         await this.loadDevices(); | ||||
|       } catch (err) { | ||||
|   | ||||
| @@ -1,14 +1,29 @@ | ||||
| import apiClient from '../api/index.js'; | ||||
| import { AreaControllerApi, DeviceApi } from '../api/device.js'; | ||||
|  | ||||
| class DeviceService { | ||||
|   /** | ||||
|    * 获取设备列表 | ||||
|    * @returns {Promise<Array>} 设备列表 | ||||
|    * 获取所有设备和区域主控的列表,并将其合并为树形结构所需的数据 | ||||
|    * @returns {Promise<Array>} 合并后的设备列表 | ||||
|    */ | ||||
|   async getDevices() { | ||||
|     try { | ||||
|       const response = await apiClient.devices.list(); | ||||
|       return response.data || []; | ||||
|       const [areaControllersResponse, devicesResponse] = await Promise.all([ | ||||
|         AreaControllerApi.list(), | ||||
|         DeviceApi.list() | ||||
|       ]); | ||||
|  | ||||
|       const areaControllers = (areaControllersResponse.data || []).map(controller => ({ | ||||
|         ...controller, | ||||
|         type: 'area_controller' // 添加类型标识 | ||||
|       })); | ||||
|  | ||||
|       const devices = (devicesResponse.data || []).map(device => ({ | ||||
|         ...device, | ||||
|         type: 'device', // 添加类型标识 | ||||
|         parent_id: device.area_controller_id // 适配前端树形结构 | ||||
|       })); | ||||
|  | ||||
|       return [...areaControllers, ...devices]; | ||||
|     } catch (error) { | ||||
|       console.error('获取设备列表失败:', error); | ||||
|       throw error; | ||||
| @@ -16,14 +31,20 @@ class DeviceService { | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * 创建新设备 | ||||
|    * @param {Object} device 设备信息 | ||||
|    * @returns {Promise<Object>} 创建的设备信息 | ||||
|    * 创建新设备或区域主控 | ||||
|    * @param {Object} deviceData 设备或区域主控信息,包含type字段 | ||||
|    * @returns {Promise<Object>} 创建结果 | ||||
|    */ | ||||
|   async createDevice(device) { | ||||
|   async createDevice(deviceData) { | ||||
|     try { | ||||
|       const response = await apiClient.devices.create(device); | ||||
|       return response.data; | ||||
|       if (deviceData.type === 'area_controller') { | ||||
|         const response = await AreaControllerApi.create(deviceData); | ||||
|         return { ...response.data, type: 'area_controller' }; | ||||
|       } else { | ||||
|         // 默认创建普通设备 | ||||
|         const response = await DeviceApi.create(deviceData); | ||||
|         return { ...response.data, type: 'device', parent_id: response.data.area_controller_id }; | ||||
|       } | ||||
|     } catch (error) { | ||||
|       console.error('创建设备失败:', error); | ||||
|       throw error; | ||||
| @@ -31,14 +52,20 @@ class DeviceService { | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * 获取设备详情 | ||||
|    * @param {number} deviceId 设备ID | ||||
|    * @returns {Promise<Object>} 设备详情 | ||||
|    * 获取设备或区域主控详情 | ||||
|    * @param {number} id ID | ||||
|    * @param {string} type 类型 ('area_controller' 或 'device') | ||||
|    * @returns {Promise<Object>} 详情 | ||||
|    */ | ||||
|   async getDevice(deviceId) { | ||||
|   async getDevice(id, type) { | ||||
|     try { | ||||
|       const response = await apiClient.devices.get(deviceId); | ||||
|       return response.data; | ||||
|       if (type === 'area_controller') { | ||||
|         const response = await AreaControllerApi.get(id); | ||||
|         return { ...response.data, type: 'area_controller' }; | ||||
|       } else { | ||||
|         const response = await DeviceApi.get(id); | ||||
|         return { ...response.data, type: 'device', parent_id: response.data.area_controller_id }; | ||||
|       } | ||||
|     } catch (error) { | ||||
|       console.error('获取设备详情失败:', error); | ||||
|       throw error; | ||||
| @@ -46,15 +73,20 @@ class DeviceService { | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * 更新设备信息 | ||||
|    * @param {number} deviceId 设备ID | ||||
|    * @param {Object} device 更新的设备信息 | ||||
|    * @returns {Promise<Object>} 更新后的设备信息 | ||||
|    * 更新设备或区域主控信息 | ||||
|    * @param {number} id ID | ||||
|    * @param {Object} deviceData 更新的设备或区域主控信息,包含type字段 | ||||
|    * @returns {Promise<Object>} 更新后的信息 | ||||
|    */ | ||||
|   async updateDevice(deviceId, device) { | ||||
|   async updateDevice(id, deviceData) { | ||||
|     try { | ||||
|       const response = await apiClient.devices.update(deviceId, device); | ||||
|       return response.data; | ||||
|       if (deviceData.type === 'area_controller') { | ||||
|         const response = await AreaControllerApi.update(id, deviceData); | ||||
|         return { ...response.data, type: 'area_controller' }; | ||||
|       } else { | ||||
|         const response = await DeviceApi.update(id, deviceData); | ||||
|         return { ...response.data, type: 'device', parent_id: response.data.area_controller_id }; | ||||
|       } | ||||
|     } catch (error) { | ||||
|       console.error('更新设备失败:', error); | ||||
|       throw error; | ||||
| @@ -62,13 +94,17 @@ class DeviceService { | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * 删除设备 | ||||
|    * @param {number} deviceId 设备ID | ||||
|    * 删除设备或区域主控 | ||||
|    * @param {Object} device 包含id和type属性的设备或区域主控对象 | ||||
|    * @returns {Promise<void>} | ||||
|    */ | ||||
|   async deleteDevice(deviceId) { | ||||
|   async deleteDevice(device) { | ||||
|     try { | ||||
|       await apiClient.devices.delete(deviceId); | ||||
|       if (device.type === 'area_controller') { | ||||
|         await AreaControllerApi.delete(device.id); | ||||
|       } else { | ||||
|         await DeviceApi.delete(device.id); | ||||
|       } | ||||
|     } catch (error) { | ||||
|       console.error('删除设备失败:', error); | ||||
|       throw error; | ||||
| @@ -77,4 +113,4 @@ class DeviceService { | ||||
| } | ||||
|  | ||||
| // 导出设备服务实例 | ||||
| export default new DeviceService(); | ||||
| export default new DeviceService(); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user