Compare commits
	
		
			2 Commits
		
	
	
		
			68e07a4d53
			...
			caaacbee44
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| caaacbee44 | |||
| ee4f498db0 | 
@@ -220,9 +220,21 @@
 | 
				
			|||||||
        "summary": "获取计划列表",
 | 
					        "summary": "获取计划列表",
 | 
				
			||||||
        "responses": {
 | 
					        "responses": {
 | 
				
			||||||
          "200": {
 | 
					          "200": {
 | 
				
			||||||
            "description": "业务失败,具体错误码和信息见响应体(例如400, 500)",
 | 
					            "description": "业务码为200代表成功获取列表",
 | 
				
			||||||
            "schema": {
 | 
					            "schema": {
 | 
				
			||||||
              "$ref": "#/definitions/controller.Response"
 | 
					              "allOf": [
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                  "$ref": "#/definitions/controller.Response"
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                  "type": "object",
 | 
				
			||||||
 | 
					                  "properties": {
 | 
				
			||||||
 | 
					                    "data": {
 | 
				
			||||||
 | 
					                      "$ref": "#/definitions/plan.ListPlansResponse"
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                  }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					              ]
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -252,9 +264,21 @@
 | 
				
			|||||||
        ],
 | 
					        ],
 | 
				
			||||||
        "responses": {
 | 
					        "responses": {
 | 
				
			||||||
          "200": {
 | 
					          "200": {
 | 
				
			||||||
            "description": "业务失败,具体错误码和信息见响应体(例如400, 500)",
 | 
					            "description": "业务码为201代表创建成功",
 | 
				
			||||||
            "schema": {
 | 
					            "schema": {
 | 
				
			||||||
              "$ref": "#/definitions/controller.Response"
 | 
					              "allOf": [
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                  "$ref": "#/definitions/controller.Response"
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                  "type": "object",
 | 
				
			||||||
 | 
					                  "properties": {
 | 
				
			||||||
 | 
					                    "data": {
 | 
				
			||||||
 | 
					                      "$ref": "#/definitions/plan.PlanResponse"
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                  }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					              ]
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -281,9 +305,21 @@
 | 
				
			|||||||
        ],
 | 
					        ],
 | 
				
			||||||
        "responses": {
 | 
					        "responses": {
 | 
				
			||||||
          "200": {
 | 
					          "200": {
 | 
				
			||||||
            "description": "业务失败,具体错误码和信息见响应体(例如400, 404, 500)",
 | 
					            "description": "业务码为200代表成功获取",
 | 
				
			||||||
            "schema": {
 | 
					            "schema": {
 | 
				
			||||||
              "$ref": "#/definitions/controller.Response"
 | 
					              "allOf": [
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                  "$ref": "#/definitions/controller.Response"
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                  "type": "object",
 | 
				
			||||||
 | 
					                  "properties": {
 | 
				
			||||||
 | 
					                    "data": {
 | 
				
			||||||
 | 
					                      "$ref": "#/definitions/plan.PlanResponse"
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                  }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					              ]
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -320,9 +356,21 @@
 | 
				
			|||||||
        ],
 | 
					        ],
 | 
				
			||||||
        "responses": {
 | 
					        "responses": {
 | 
				
			||||||
          "200": {
 | 
					          "200": {
 | 
				
			||||||
            "description": "业务失败,具体错误码和信息见响应体(例如400, 404, 500)",
 | 
					            "description": "业务码为200代表更新成功",
 | 
				
			||||||
            "schema": {
 | 
					            "schema": {
 | 
				
			||||||
              "$ref": "#/definitions/controller.Response"
 | 
					              "allOf": [
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                  "$ref": "#/definitions/controller.Response"
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                  "type": "object",
 | 
				
			||||||
 | 
					                  "properties": {
 | 
				
			||||||
 | 
					                    "data": {
 | 
				
			||||||
 | 
					                      "$ref": "#/definitions/plan.PlanResponse"
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                  }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					              ]
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -347,7 +395,7 @@
 | 
				
			|||||||
        ],
 | 
					        ],
 | 
				
			||||||
        "responses": {
 | 
					        "responses": {
 | 
				
			||||||
          "200": {
 | 
					          "200": {
 | 
				
			||||||
            "description": "业务失败,具体错误码和信息见响应体(例如400, 404, 500)",
 | 
					            "description": "业务码为200代表删除成功",
 | 
				
			||||||
            "schema": {
 | 
					            "schema": {
 | 
				
			||||||
              "$ref": "#/definitions/controller.Response"
 | 
					              "$ref": "#/definitions/controller.Response"
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@@ -376,7 +424,7 @@
 | 
				
			|||||||
        ],
 | 
					        ],
 | 
				
			||||||
        "responses": {
 | 
					        "responses": {
 | 
				
			||||||
          "200": {
 | 
					          "200": {
 | 
				
			||||||
            "description": "业务失败,具体错误码和信息见响应体(例如400, 404, 500)",
 | 
					            "description": "业务码为200代表成功启动计划",
 | 
				
			||||||
            "schema": {
 | 
					            "schema": {
 | 
				
			||||||
              "$ref": "#/definitions/controller.Response"
 | 
					              "$ref": "#/definitions/controller.Response"
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@@ -405,7 +453,7 @@
 | 
				
			|||||||
        ],
 | 
					        ],
 | 
				
			||||||
        "responses": {
 | 
					        "responses": {
 | 
				
			||||||
          "200": {
 | 
					          "200": {
 | 
				
			||||||
            "description": "业务失败,具体错误码和信息见响应体(例如400, 404, 500)",
 | 
					            "description": "业务码为200代表成功停止计划",
 | 
				
			||||||
            "schema": {
 | 
					            "schema": {
 | 
				
			||||||
              "$ref": "#/definitions/controller.Response"
 | 
					              "$ref": "#/definitions/controller.Response"
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@@ -439,9 +487,21 @@
 | 
				
			|||||||
        ],
 | 
					        ],
 | 
				
			||||||
        "responses": {
 | 
					        "responses": {
 | 
				
			||||||
          "200": {
 | 
					          "200": {
 | 
				
			||||||
            "description": "业务失败,具体错误码和信息见响应体(例如400, 409, 500)",
 | 
					            "description": "业务码为201代表创建成功",
 | 
				
			||||||
            "schema": {
 | 
					            "schema": {
 | 
				
			||||||
              "$ref": "#/definitions/controller.Response"
 | 
					              "allOf": [
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                  "$ref": "#/definitions/controller.Response"
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                  "type": "object",
 | 
				
			||||||
 | 
					                  "properties": {
 | 
				
			||||||
 | 
					                    "data": {
 | 
				
			||||||
 | 
					                      "$ref": "#/definitions/user.CreateUserResponse"
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                  }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					              ]
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -473,9 +533,21 @@
 | 
				
			|||||||
        ],
 | 
					        ],
 | 
				
			||||||
        "responses": {
 | 
					        "responses": {
 | 
				
			||||||
          "200": {
 | 
					          "200": {
 | 
				
			||||||
            "description": "业务失败,具体错误码和信息见响应体(例如400, 401, 500)",
 | 
					            "description": "业务码为200代表登录成功",
 | 
				
			||||||
            "schema": {
 | 
					            "schema": {
 | 
				
			||||||
              "$ref": "#/definitions/controller.Response"
 | 
					              "allOf": [
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                  "$ref": "#/definitions/controller.Response"
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                  "type": "object",
 | 
				
			||||||
 | 
					                  "properties": {
 | 
				
			||||||
 | 
					                    "data": {
 | 
				
			||||||
 | 
					                      "$ref": "#/definitions/user.LoginResponse"
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                  }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					              ]
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -483,9 +555,6 @@
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "definitions": {
 | 
					  "definitions": {
 | 
				
			||||||
    "controller.Properties": {
 | 
					 | 
				
			||||||
      "type": "object"
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    "controller.Response": {
 | 
					    "controller.Response": {
 | 
				
			||||||
      "type": "object",
 | 
					      "type": "object",
 | 
				
			||||||
      "properties": {
 | 
					      "properties": {
 | 
				
			||||||
@@ -519,7 +588,8 @@
 | 
				
			|||||||
          "type": "integer"
 | 
					          "type": "integer"
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        "properties": {
 | 
					        "properties": {
 | 
				
			||||||
          "$ref": "#/definitions/controller.Properties"
 | 
					          "type": "object",
 | 
				
			||||||
 | 
					          "additionalProperties": true
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        "sub_type": {
 | 
					        "sub_type": {
 | 
				
			||||||
          "$ref": "#/definitions/models.DeviceSubType"
 | 
					          "$ref": "#/definitions/models.DeviceSubType"
 | 
				
			||||||
@@ -546,7 +616,8 @@
 | 
				
			|||||||
          "type": "integer"
 | 
					          "type": "integer"
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        "properties": {
 | 
					        "properties": {
 | 
				
			||||||
          "$ref": "#/definitions/controller.Properties"
 | 
					          "type": "object",
 | 
				
			||||||
 | 
					          "additionalProperties": true
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        "sub_type": {
 | 
					        "sub_type": {
 | 
				
			||||||
          "$ref": "#/definitions/models.DeviceSubType"
 | 
					          "$ref": "#/definitions/models.DeviceSubType"
 | 
				
			||||||
@@ -575,7 +646,8 @@
 | 
				
			|||||||
          "type": "integer"
 | 
					          "type": "integer"
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        "properties": {
 | 
					        "properties": {
 | 
				
			||||||
          "$ref": "#/definitions/controller.Properties"
 | 
					          "type": "object",
 | 
				
			||||||
 | 
					          "additionalProperties": true
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        "sub_type": {
 | 
					        "sub_type": {
 | 
				
			||||||
          "$ref": "#/definitions/models.DeviceSubType"
 | 
					          "$ref": "#/definitions/models.DeviceSubType"
 | 
				
			||||||
@@ -875,7 +947,8 @@
 | 
				
			|||||||
          "example": "打开风扇"
 | 
					          "example": "打开风扇"
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        "parameters": {
 | 
					        "parameters": {
 | 
				
			||||||
          "$ref": "#/definitions/controller.Properties"
 | 
					          "type": "object",
 | 
				
			||||||
 | 
					          "additionalProperties": true
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        "type": {
 | 
					        "type": {
 | 
				
			||||||
          "allOf": [
 | 
					          "allOf": [
 | 
				
			||||||
@@ -907,7 +980,8 @@
 | 
				
			|||||||
          "example": "打开风扇"
 | 
					          "example": "打开风扇"
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        "parameters": {
 | 
					        "parameters": {
 | 
				
			||||||
          "$ref": "#/definitions/controller.Properties"
 | 
					          "type": "object",
 | 
				
			||||||
 | 
					          "additionalProperties": true
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        "plan_id": {
 | 
					        "plan_id": {
 | 
				
			||||||
          "type": "integer",
 | 
					          "type": "integer",
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										332
									
								
								src/components/DeviceForm.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										332
									
								
								src/components/DeviceForm.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,332 @@
 | 
				
			|||||||
 | 
					<template>
 | 
				
			||||||
 | 
					  <el-dialog
 | 
				
			||||||
 | 
					    :model-value="visible"
 | 
				
			||||||
 | 
					    :title="title"
 | 
				
			||||||
 | 
					    @close="handleClose"
 | 
				
			||||||
 | 
					    :close-on-click-modal="false"
 | 
				
			||||||
 | 
					    width="600px"
 | 
				
			||||||
 | 
					  >
 | 
				
			||||||
 | 
					    <el-form
 | 
				
			||||||
 | 
					      ref="formRef"
 | 
				
			||||||
 | 
					      :model="formData"
 | 
				
			||||||
 | 
					      :rules="rules"
 | 
				
			||||||
 | 
					      label-width="120px"
 | 
				
			||||||
 | 
					      @submit.prevent
 | 
				
			||||||
 | 
					    >
 | 
				
			||||||
 | 
					      <!-- 基础信息 -->
 | 
				
			||||||
 | 
					      <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-option label="区域主控" value="area_controller" />
 | 
				
			||||||
 | 
					          <el-option label="普通设备" value="device" />
 | 
				
			||||||
 | 
					        </el-select>
 | 
				
			||||||
 | 
					      </el-form-item>
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      <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>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      <!-- 普通设备类型额外字段 -->
 | 
				
			||||||
 | 
					      <div v-if="formData.type === 'device'">
 | 
				
			||||||
 | 
					        <el-form-item label="区域主控" prop="parentControllerId">
 | 
				
			||||||
 | 
					          <el-select v-model="formData.parentControllerId" placeholder="请选择区域主控">
 | 
				
			||||||
 | 
					            <el-option
 | 
				
			||||||
 | 
					              v-for="controller in areaControllers"
 | 
				
			||||||
 | 
					              :key="controller.id"
 | 
				
			||||||
 | 
					              :label="controller.name"
 | 
				
			||||||
 | 
					              :value="controller.id"
 | 
				
			||||||
 | 
					            />
 | 
				
			||||||
 | 
					          </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-select>
 | 
				
			||||||
 | 
					        </el-form-item>
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        <el-form-item label="485总线号" prop="busNumber">
 | 
				
			||||||
 | 
					          <el-input-number 
 | 
				
			||||||
 | 
					            v-model="formData.busNumber" 
 | 
				
			||||||
 | 
					            :min="0"
 | 
				
			||||||
 | 
					            controls-position="right"
 | 
				
			||||||
 | 
					            style="width: 100%"
 | 
				
			||||||
 | 
					          />
 | 
				
			||||||
 | 
					        </el-form-item>
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        <el-form-item label="485总线地址" prop="busAddress">
 | 
				
			||||||
 | 
					          <el-input-number 
 | 
				
			||||||
 | 
					            v-model="formData.busAddress" 
 | 
				
			||||||
 | 
					            :min="0"
 | 
				
			||||||
 | 
					            controls-position="right"
 | 
				
			||||||
 | 
					            style="width: 100%"
 | 
				
			||||||
 | 
					          />
 | 
				
			||||||
 | 
					        </el-form-item>
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        <el-form-item label="继电器通道号" prop="relayChannel">
 | 
				
			||||||
 | 
					          <el-input-number 
 | 
				
			||||||
 | 
					            v-model="formData.relayChannel" 
 | 
				
			||||||
 | 
					            :min="0"
 | 
				
			||||||
 | 
					            controls-position="right"
 | 
				
			||||||
 | 
					            style="width: 100%"
 | 
				
			||||||
 | 
					          />
 | 
				
			||||||
 | 
					        </el-form-item>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    </el-form>
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    <template #footer>
 | 
				
			||||||
 | 
					      <span class="dialog-footer">
 | 
				
			||||||
 | 
					        <el-button @click="handleClose">取消</el-button>
 | 
				
			||||||
 | 
					        <el-button type="primary" @click="handleSubmit" :loading="loading">确定</el-button>
 | 
				
			||||||
 | 
					      </span>
 | 
				
			||||||
 | 
					    </template>
 | 
				
			||||||
 | 
					  </el-dialog>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script>
 | 
				
			||||||
 | 
					import { ref, reactive, onMounted, watch, computed } from 'vue';
 | 
				
			||||||
 | 
					import { ElMessage } from 'element-plus';
 | 
				
			||||||
 | 
					import { DeviceApi } from '../api/device.js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default {
 | 
				
			||||||
 | 
					  name: 'DeviceForm',
 | 
				
			||||||
 | 
					  props: {
 | 
				
			||||||
 | 
					    visible: {
 | 
				
			||||||
 | 
					      type: Boolean,
 | 
				
			||||||
 | 
					      default: false
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    deviceData: {
 | 
				
			||||||
 | 
					      type: Object,
 | 
				
			||||||
 | 
					      default: () => ({})
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    isEdit: {
 | 
				
			||||||
 | 
					      type: Boolean,
 | 
				
			||||||
 | 
					      default: false
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  emits: ['update:visible', 'success', 'cancel'],
 | 
				
			||||||
 | 
					  setup(props, { emit }) {
 | 
				
			||||||
 | 
					    // 表单引用
 | 
				
			||||||
 | 
					    const formRef = ref(null);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // 加载状态
 | 
				
			||||||
 | 
					    const loading = ref(false);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // 区域主控列表
 | 
				
			||||||
 | 
					    const areaControllers = ref([]);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // 表单数据
 | 
				
			||||||
 | 
					    const formData = reactive({
 | 
				
			||||||
 | 
					      id: '',
 | 
				
			||||||
 | 
					      name: '',
 | 
				
			||||||
 | 
					      type: '',
 | 
				
			||||||
 | 
					      location: '',
 | 
				
			||||||
 | 
					      // 区域主控字段
 | 
				
			||||||
 | 
					      loraAddress: '',
 | 
				
			||||||
 | 
					      // 普通设备字段
 | 
				
			||||||
 | 
					      parentControllerId: '',
 | 
				
			||||||
 | 
					      subType: '',
 | 
				
			||||||
 | 
					      busNumber: 0,
 | 
				
			||||||
 | 
					      busAddress: 0,
 | 
				
			||||||
 | 
					      relayChannel: 0
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // 表单验证规则
 | 
				
			||||||
 | 
					    const rules = {
 | 
				
			||||||
 | 
					      name: [
 | 
				
			||||||
 | 
					        { required: true, message: '请输入设备名', trigger: 'blur' }
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      type: [
 | 
				
			||||||
 | 
					        { required: true, message: '请选择设备类型', trigger: 'change' }
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      location: [
 | 
				
			||||||
 | 
					        { required: true, message: '请输入设备位置描述', trigger: 'blur' }
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      loraAddress: [
 | 
				
			||||||
 | 
					        { required: true, message: '请输入LoRa地址', trigger: 'blur' }
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      parentControllerId: [
 | 
				
			||||||
 | 
					        { required: true, message: '请选择区域主控', trigger: 'change' }
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      subType: [
 | 
				
			||||||
 | 
					        { required: true, message: '请选择设备种类', trigger: 'change' }
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      busNumber: [
 | 
				
			||||||
 | 
					        { required: true, message: '请输入485总线号', trigger: 'blur' }
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      busAddress: [
 | 
				
			||||||
 | 
					        { required: true, message: '请输入485总线地址', trigger: 'blur' }
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      relayChannel: [
 | 
				
			||||||
 | 
					        { required: true, 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;
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        // 清除区域主控字段
 | 
				
			||||||
 | 
					        formData.loraAddress = '';
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // 获取区域主控列表
 | 
				
			||||||
 | 
					    const loadAreaControllers = async () => {
 | 
				
			||||||
 | 
					      try {
 | 
				
			||||||
 | 
					        const response = await DeviceApi.list();
 | 
				
			||||||
 | 
					        // 筛选出类型为区域主控的设备
 | 
				
			||||||
 | 
					        areaControllers.value = response.data.filter(device => device.type === 'area_controller');
 | 
				
			||||||
 | 
					      } catch (error) {
 | 
				
			||||||
 | 
					        console.error('获取区域主控列表失败:', error);
 | 
				
			||||||
 | 
					        areaControllers.value = [];
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // 关闭对话框
 | 
				
			||||||
 | 
					    const handleClose = () => {
 | 
				
			||||||
 | 
					      emit('update:visible', false);
 | 
				
			||||||
 | 
					      emit('cancel');
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // 提交表单
 | 
				
			||||||
 | 
					    const handleSubmit = async () => {
 | 
				
			||||||
 | 
					      await formRef.value.validate(async (valid) => {
 | 
				
			||||||
 | 
					        if (valid) {
 | 
				
			||||||
 | 
					          loading.value = true;
 | 
				
			||||||
 | 
					          try {
 | 
				
			||||||
 | 
					            let result;
 | 
				
			||||||
 | 
					            if (props.isEdit) {
 | 
				
			||||||
 | 
					              // 编辑设备
 | 
				
			||||||
 | 
					              result = await DeviceApi.update(formData.id, getSubmitData());
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					              // 创建设备
 | 
				
			||||||
 | 
					              result = await DeviceApi.create(getSubmitData());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            emit('success', result);
 | 
				
			||||||
 | 
					            handleClose();
 | 
				
			||||||
 | 
					          } catch (error) {
 | 
				
			||||||
 | 
					            console.error('保存设备失败:', error);
 | 
				
			||||||
 | 
					            ElMessage.error(props.isEdit ? '编辑设备失败' : '创建设备失败');
 | 
				
			||||||
 | 
					          } finally {
 | 
				
			||||||
 | 
					            loading.value = false;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // 获取提交数据
 | 
				
			||||||
 | 
					    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 => {
 | 
				
			||||||
 | 
					          if (newVal[key] !== undefined) {
 | 
				
			||||||
 | 
					            formData[key] = newVal[key];
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        // 处理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;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        // 重置表单数据
 | 
				
			||||||
 | 
					        Object.keys(formData).forEach(key => {
 | 
				
			||||||
 | 
					          if (key === 'busNumber' || key === 'busAddress' || key === 'relayChannel') {
 | 
				
			||||||
 | 
					            formData[key] = 0;
 | 
				
			||||||
 | 
					          } else {
 | 
				
			||||||
 | 
					            formData[key] = '';
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }, { immediate: true });
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // 组件挂载时加载区域主控列表
 | 
				
			||||||
 | 
					    onMounted(() => {
 | 
				
			||||||
 | 
					      loadAreaControllers();
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    return {
 | 
				
			||||||
 | 
					      formRef,
 | 
				
			||||||
 | 
					      loading,
 | 
				
			||||||
 | 
					      areaControllers,
 | 
				
			||||||
 | 
					      formData,
 | 
				
			||||||
 | 
					      rules,
 | 
				
			||||||
 | 
					      title,
 | 
				
			||||||
 | 
					      handleTypeChange,
 | 
				
			||||||
 | 
					      handleClose,
 | 
				
			||||||
 | 
					      handleSubmit
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style scoped>
 | 
				
			||||||
 | 
					.dialog-footer {
 | 
				
			||||||
 | 
					  display: flex;
 | 
				
			||||||
 | 
					  justify-content: flex-end;
 | 
				
			||||||
 | 
					  gap: 10px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
@@ -27,19 +27,27 @@
 | 
				
			|||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
      <!-- 设备列表 -->
 | 
					      <!-- 设备列表 -->
 | 
				
			||||||
      <el-table v-else :data="devices" style="width: 100%">
 | 
					      <el-table 
 | 
				
			||||||
        <el-table-column prop="id" label="设备ID" width="180" />
 | 
					        v-else 
 | 
				
			||||||
        <el-table-column prop="name" label="设备名称" width="180" />
 | 
					        :data="devices" 
 | 
				
			||||||
        <el-table-column prop="type" label="设备类型" />
 | 
					        style="width: 100%"
 | 
				
			||||||
        <el-table-column prop="status" label="状态">
 | 
					        :fit="true"
 | 
				
			||||||
 | 
					        table-layout="auto">
 | 
				
			||||||
 | 
					        <el-table-column prop="id" label="设备ID" min-width="80" />
 | 
				
			||||||
 | 
					        <el-table-column prop="name" label="设备名称" min-width="120" />
 | 
				
			||||||
 | 
					        <el-table-column prop="type" label="设备类型" min-width="100">
 | 
				
			||||||
          <template #default="scope">
 | 
					          <template #default="scope">
 | 
				
			||||||
            <el-tag :type="scope.row.status === 'online' ? 'success' : 'danger'">
 | 
					            {{ formatDeviceType(scope.row.type) }}
 | 
				
			||||||
              {{ scope.row.status === 'online' ? '在线' : '离线' }}
 | 
					 | 
				
			||||||
            </el-tag>
 | 
					 | 
				
			||||||
          </template>
 | 
					          </template>
 | 
				
			||||||
        </el-table-column>
 | 
					        </el-table-column>
 | 
				
			||||||
        <el-table-column prop="lastUpdate" label="最后更新" />
 | 
					        <el-table-column prop="sub_type" label="设备子类型" min-width="100">
 | 
				
			||||||
        <el-table-column label="操作">
 | 
					          <template #default="scope">
 | 
				
			||||||
 | 
					            {{ formatDeviceSubType(scope.row.sub_type) }}
 | 
				
			||||||
 | 
					          </template>
 | 
				
			||||||
 | 
					        </el-table-column>
 | 
				
			||||||
 | 
					        <el-table-column prop="location" label="设备地址描述" min-width="150" />
 | 
				
			||||||
 | 
					        <el-table-column prop="parentName" label="上级设备名" min-width="120" />
 | 
				
			||||||
 | 
					        <el-table-column label="操作" min-width="120" align="center">
 | 
				
			||||||
          <template #default="scope">
 | 
					          <template #default="scope">
 | 
				
			||||||
            <el-button size="small" @click="editDevice(scope.row)">编辑</el-button>
 | 
					            <el-button size="small" @click="editDevice(scope.row)">编辑</el-button>
 | 
				
			||||||
            <el-button size="small" type="danger" @click="deleteDevice(scope.row)">删除</el-button>
 | 
					            <el-button size="small" type="danger" @click="deleteDevice(scope.row)">删除</el-button>
 | 
				
			||||||
@@ -48,55 +56,35 @@
 | 
				
			|||||||
      </el-table>
 | 
					      </el-table>
 | 
				
			||||||
    </el-card>
 | 
					    </el-card>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <!-- 添加/编辑设备对话框 -->
 | 
					    <!-- 设备表单对话框 -->
 | 
				
			||||||
    <el-dialog v-model="dialogVisible" :title="dialogTitle">
 | 
					    <DeviceForm 
 | 
				
			||||||
      <el-form :model="currentDevice" label-width="120px">
 | 
					      v-model:visible="dialogVisible" 
 | 
				
			||||||
        <el-form-item label="设备名称">
 | 
					      :device-data="currentDevice" 
 | 
				
			||||||
          <el-input v-model="currentDevice.name" />
 | 
					      :is-edit="isEdit"
 | 
				
			||||||
        </el-form-item>
 | 
					      @success="onDeviceSuccess"
 | 
				
			||||||
        <el-form-item label="设备类型">
 | 
					      @cancel="dialogVisible = false"
 | 
				
			||||||
          <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>
 | 
					  </div>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script>
 | 
					<script>
 | 
				
			||||||
import deviceService from '../services/deviceService.js';
 | 
					import deviceService from '../services/deviceService.js';
 | 
				
			||||||
 | 
					import DeviceForm from './DeviceForm.vue';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default {
 | 
					export default {
 | 
				
			||||||
  name: 'DeviceList',
 | 
					  name: 'DeviceList',
 | 
				
			||||||
 | 
					  components: {
 | 
				
			||||||
 | 
					    DeviceForm
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
  data() {
 | 
					  data() {
 | 
				
			||||||
    return {
 | 
					    return {
 | 
				
			||||||
      devices: [],
 | 
					      devices: [],
 | 
				
			||||||
 | 
					      allDevices: [], // 存储所有设备用于查找上级设备
 | 
				
			||||||
      loading: false,
 | 
					      loading: false,
 | 
				
			||||||
      error: null,
 | 
					      error: null,
 | 
				
			||||||
      saving: false,
 | 
					      saving: false,
 | 
				
			||||||
      dialogVisible: false,
 | 
					      dialogVisible: false,
 | 
				
			||||||
      dialogTitle: '',
 | 
					      currentDevice: {},
 | 
				
			||||||
      currentDevice: {
 | 
					 | 
				
			||||||
        id: '',
 | 
					 | 
				
			||||||
        name: '',
 | 
					 | 
				
			||||||
        type: '',
 | 
					 | 
				
			||||||
        status: 'online'
 | 
					 | 
				
			||||||
      },
 | 
					 | 
				
			||||||
      isEdit: false
 | 
					      isEdit: false
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
@@ -111,12 +99,22 @@ export default {
 | 
				
			|||||||
      
 | 
					      
 | 
				
			||||||
      try {
 | 
					      try {
 | 
				
			||||||
        const data = await deviceService.getDevices();
 | 
					        const data = await deviceService.getDevices();
 | 
				
			||||||
        this.devices = data.map(device => ({
 | 
					        // 保存所有设备数据
 | 
				
			||||||
          ...device,
 | 
					        this.allDevices = data;
 | 
				
			||||||
          // 格式化数据显示
 | 
					        // 处理设备数据,添加上级设备名称
 | 
				
			||||||
          type: this.formatDeviceType(device.type),
 | 
					        this.devices = data.map(device => {
 | 
				
			||||||
          lastUpdate: device.updated_at || '-'
 | 
					          // 查找上级设备名称
 | 
				
			||||||
        }));
 | 
					          let parentName = '-';
 | 
				
			||||||
 | 
					          if (device.parent_id) {
 | 
				
			||||||
 | 
					            const parentDevice = data.find(d => d.id === device.parent_id);
 | 
				
			||||||
 | 
					            parentName = parentDevice ? parentDevice.name : '-';
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          
 | 
				
			||||||
 | 
					          return {
 | 
				
			||||||
 | 
					            ...device,
 | 
				
			||||||
 | 
					            parentName
 | 
				
			||||||
 | 
					          };
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
      } catch (err) {
 | 
					      } catch (err) {
 | 
				
			||||||
        this.error = err.message || '未知错误';
 | 
					        this.error = err.message || '未知错误';
 | 
				
			||||||
        console.error('加载设备列表失败:', err);
 | 
					        console.error('加载设备列表失败:', err);
 | 
				
			||||||
@@ -128,38 +126,34 @@ export default {
 | 
				
			|||||||
    // 格式化设备类型显示
 | 
					    // 格式化设备类型显示
 | 
				
			||||||
    formatDeviceType(type) {
 | 
					    formatDeviceType(type) {
 | 
				
			||||||
      const typeMap = {
 | 
					      const typeMap = {
 | 
				
			||||||
        'sensor': '传感器',
 | 
					        'area_controller': '区域主控',
 | 
				
			||||||
        'controller': '控制器',
 | 
					        'device': '普通设备'
 | 
				
			||||||
        'camera': '摄像头'
 | 
					 | 
				
			||||||
      };
 | 
					      };
 | 
				
			||||||
      return typeMap[type] || type;
 | 
					      return typeMap[type] || type || '-';
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // 格式化设备子类型显示
 | 
				
			||||||
 | 
					    formatDeviceSubType(subType) {
 | 
				
			||||||
 | 
					      const subTypeMap = {
 | 
				
			||||||
 | 
					        '': '-',
 | 
				
			||||||
 | 
					        'temperature': '温度传感器',
 | 
				
			||||||
 | 
					        'humidity': '湿度传感器',
 | 
				
			||||||
 | 
					        'ammonia': '氨气传感器',
 | 
				
			||||||
 | 
					        'feed_valve': '饲料阀门',
 | 
				
			||||||
 | 
					        'fan': '风扇',
 | 
				
			||||||
 | 
					        'water_curtain': '水帘'
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					      return subTypeMap[subType] || subType || '-';
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    addDevice() {
 | 
					    addDevice() {
 | 
				
			||||||
      this.dialogTitle = '添加设备';
 | 
					      this.currentDevice = {};
 | 
				
			||||||
      this.currentDevice = {
 | 
					 | 
				
			||||||
        id: '',
 | 
					 | 
				
			||||||
        name: '',
 | 
					 | 
				
			||||||
        type: '',
 | 
					 | 
				
			||||||
        status: 'online'
 | 
					 | 
				
			||||||
      };
 | 
					 | 
				
			||||||
      this.isEdit = false;
 | 
					      this.isEdit = false;
 | 
				
			||||||
      this.dialogVisible = true;
 | 
					      this.dialogVisible = true;
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    editDevice(device) {
 | 
					    editDevice(device) {
 | 
				
			||||||
      this.dialogTitle = '编辑设备';
 | 
					      this.currentDevice = { ...device };
 | 
				
			||||||
      // 注意:这里需要将显示值转换回API值
 | 
					 | 
				
			||||||
      const typeMap = {
 | 
					 | 
				
			||||||
        '传感器': 'sensor',
 | 
					 | 
				
			||||||
        '控制器': 'controller',
 | 
					 | 
				
			||||||
        '摄像头': 'camera'
 | 
					 | 
				
			||||||
      };
 | 
					 | 
				
			||||||
      
 | 
					 | 
				
			||||||
      this.currentDevice = { 
 | 
					 | 
				
			||||||
        ...device,
 | 
					 | 
				
			||||||
        type: typeMap[device.type] || device.type
 | 
					 | 
				
			||||||
      };
 | 
					 | 
				
			||||||
      this.isEdit = true;
 | 
					      this.isEdit = true;
 | 
				
			||||||
      this.dialogVisible = true;
 | 
					      this.dialogVisible = true;
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
@@ -183,28 +177,12 @@ export default {
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    async saveDevice() {
 | 
					    // 设备操作成功回调
 | 
				
			||||||
      this.saving = true;
 | 
					    async onDeviceSuccess() {
 | 
				
			||||||
      
 | 
					      this.$message.success(this.isEdit ? '设备更新成功' : '设备添加成功');
 | 
				
			||||||
      try {
 | 
					      this.dialogVisible = false;
 | 
				
			||||||
        if (this.isEdit) {
 | 
					      // 重新加载设备列表
 | 
				
			||||||
          // 编辑设备
 | 
					      await this.loadDevices();
 | 
				
			||||||
          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;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user