添加区域主控相关路由
This commit is contained in:
586
docs/docs.go
586
docs/docs.go
@@ -15,6 +15,204 @@ const docTemplate = `{
|
|||||||
"host": "{{.Host}}",
|
"host": "{{.Host}}",
|
||||||
"basePath": "{{.BasePath}}",
|
"basePath": "{{.BasePath}}",
|
||||||
"paths": {
|
"paths": {
|
||||||
|
"/api/v1/area-controllers": {
|
||||||
|
"get": {
|
||||||
|
"description": "获取系统中所有区域主控的列表",
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"区域主控管理"
|
||||||
|
],
|
||||||
|
"summary": "获取所有区域主控列表",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/controller.Response"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/device.AreaControllerResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"post": {
|
||||||
|
"description": "根据提供的信息创建一个新区域主控",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"区域主控管理"
|
||||||
|
],
|
||||||
|
"summary": "创建新区域主控",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "区域主控信息",
|
||||||
|
"name": "areaController",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/device.CreateAreaControllerRequest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/controller.Response"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"$ref": "#/definitions/device.AreaControllerResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/v1/area-controllers/{id}": {
|
||||||
|
"get": {
|
||||||
|
"description": "根据ID获取单个区域主控的详细信息",
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"区域主控管理"
|
||||||
|
],
|
||||||
|
"summary": "获取区域主控信息",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "区域主控ID",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/controller.Response"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"$ref": "#/definitions/device.AreaControllerResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"put": {
|
||||||
|
"description": "根据ID更新一个已存在的区域主控信息",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"区域主控管理"
|
||||||
|
],
|
||||||
|
"summary": "更新区域主控信息",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "区域主控ID",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "要更新的区域主控信息",
|
||||||
|
"name": "areaController",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/device.UpdateAreaControllerRequest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/controller.Response"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"$ref": "#/definitions/device.AreaControllerResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"delete": {
|
||||||
|
"description": "根据ID删除一个区域主控(软删除)",
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"区域主控管理"
|
||||||
|
],
|
||||||
|
"summary": "删除区域主控",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "区域主控ID",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/controller.Response"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/api/v1/devices": {
|
"/api/v1/devices": {
|
||||||
"get": {
|
"get": {
|
||||||
"description": "获取系统中所有设备的列表",
|
"description": "获取系统中所有设备的列表",
|
||||||
@@ -381,7 +579,7 @@ const docTemplate = `{
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"delete": {
|
"delete": {
|
||||||
"description": "根据计划ID删除计划。",
|
"description": "根据计划ID删除计划。(软删除)",
|
||||||
"produces": [
|
"produces": [
|
||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
@@ -514,7 +712,7 @@ const docTemplate = `{
|
|||||||
},
|
},
|
||||||
"/api/v1/users/login": {
|
"/api/v1/users/login": {
|
||||||
"post": {
|
"post": {
|
||||||
"description": "用户使用用户名和密码登录,成功后返回 JWT 令牌。",
|
"description": "用户可以使用用户名、邮箱、手机号、微信号或飞书账号进行登录,成功后返回 JWT 令牌。",
|
||||||
"consumes": [
|
"consumes": [
|
||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
@@ -557,6 +755,67 @@ const docTemplate = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"/api/v1/users/{id}/history": {
|
||||||
|
"get": {
|
||||||
|
"description": "根据用户ID,分页获取该用户的操作审计日志。",
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"用户管理"
|
||||||
|
],
|
||||||
|
"summary": "获取指定用户的操作历史",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "用户ID",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"default": 1,
|
||||||
|
"description": "页码",
|
||||||
|
"name": "page",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"default": 10,
|
||||||
|
"description": "每页大小",
|
||||||
|
"name": "page_size",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "按操作类型过滤",
|
||||||
|
"name": "action_type",
|
||||||
|
"in": "query"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "业务码为200代表成功获取",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/controller.Response"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"$ref": "#/definitions/user.ListHistoryResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"definitions": {
|
"definitions": {
|
||||||
@@ -565,7 +824,11 @@ const docTemplate = `{
|
|||||||
"properties": {
|
"properties": {
|
||||||
"code": {
|
"code": {
|
||||||
"description": "业务状态码",
|
"description": "业务状态码",
|
||||||
"type": "integer"
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/controller.ResponseCode"
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"data": {
|
"data": {
|
||||||
"description": "业务数据"
|
"description": "业务数据"
|
||||||
@@ -576,63 +839,50 @@ const docTemplate = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"device.CreateDeviceRequest": {
|
"controller.ResponseCode": {
|
||||||
"type": "object",
|
"type": "integer",
|
||||||
"required": [
|
"enum": [
|
||||||
"name",
|
2000,
|
||||||
"type"
|
2001,
|
||||||
|
4000,
|
||||||
|
4001,
|
||||||
|
4004,
|
||||||
|
4009,
|
||||||
|
5000,
|
||||||
|
5003
|
||||||
],
|
],
|
||||||
"properties": {
|
"x-enum-comments": {
|
||||||
"location": {
|
"CodeBadRequest": "请求参数错误",
|
||||||
"type": "string"
|
"CodeConflict": "资源冲突",
|
||||||
|
"CodeCreated": "创建成功",
|
||||||
|
"CodeInternalError": "服务器内部错误",
|
||||||
|
"CodeNotFound": "资源未找到",
|
||||||
|
"CodeServiceUnavailable": "服务不可用",
|
||||||
|
"CodeSuccess": "操作成功",
|
||||||
|
"CodeUnauthorized": "未授权"
|
||||||
},
|
},
|
||||||
"name": {
|
"x-enum-descriptions": [
|
||||||
"type": "string"
|
"操作成功",
|
||||||
},
|
"创建成功",
|
||||||
"parent_id": {
|
"请求参数错误",
|
||||||
"type": "integer"
|
"未授权",
|
||||||
},
|
"资源未找到",
|
||||||
"properties": {
|
"资源冲突",
|
||||||
"type": "object",
|
"服务器内部错误",
|
||||||
"additionalProperties": true
|
"服务不可用"
|
||||||
},
|
|
||||||
"sub_type": {
|
|
||||||
"$ref": "#/definitions/models.DeviceSubType"
|
|
||||||
},
|
|
||||||
"type": {
|
|
||||||
"$ref": "#/definitions/models.DeviceType"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"device.UpdateDeviceRequest": {
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"name",
|
|
||||||
"type"
|
|
||||||
],
|
],
|
||||||
"properties": {
|
"x-enum-varnames": [
|
||||||
"location": {
|
"CodeSuccess",
|
||||||
"type": "string"
|
"CodeCreated",
|
||||||
|
"CodeBadRequest",
|
||||||
|
"CodeUnauthorized",
|
||||||
|
"CodeNotFound",
|
||||||
|
"CodeConflict",
|
||||||
|
"CodeInternalError",
|
||||||
|
"CodeServiceUnavailable"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"name": {
|
"device.AreaControllerResponse": {
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"parent_id": {
|
|
||||||
"type": "integer"
|
|
||||||
},
|
|
||||||
"properties": {
|
|
||||||
"type": "object",
|
|
||||||
"additionalProperties": true
|
|
||||||
},
|
|
||||||
"sub_type": {
|
|
||||||
"$ref": "#/definitions/models.DeviceSubType"
|
|
||||||
},
|
|
||||||
"type": {
|
|
||||||
"$ref": "#/definitions/models.DeviceType"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"git_huangwc_com_pig_pig-farm-controller_internal_app_controller_device.DeviceResponse": {
|
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"created_at": {
|
"created_at": {
|
||||||
@@ -647,57 +897,152 @@ const docTemplate = `{
|
|||||||
"name": {
|
"name": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"parent_id": {
|
"network_id": {
|
||||||
"type": "integer"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"properties": {
|
"properties": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"additionalProperties": true
|
"additionalProperties": true
|
||||||
},
|
},
|
||||||
"sub_type": {
|
"status": {
|
||||||
"$ref": "#/definitions/models.DeviceSubType"
|
"type": "string"
|
||||||
},
|
|
||||||
"type": {
|
|
||||||
"$ref": "#/definitions/models.DeviceType"
|
|
||||||
},
|
},
|
||||||
"updated_at": {
|
"updated_at": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"models.DeviceSubType": {
|
"device.CreateAreaControllerRequest": {
|
||||||
"type": "string",
|
"type": "object",
|
||||||
"enum": [
|
"required": [
|
||||||
"",
|
"name",
|
||||||
"temperature",
|
"network_id"
|
||||||
"humidity",
|
|
||||||
"ammonia",
|
|
||||||
"weight",
|
|
||||||
"feed_valve",
|
|
||||||
"fan",
|
|
||||||
"water_curtain"
|
|
||||||
],
|
],
|
||||||
"x-enum-varnames": [
|
"properties": {
|
||||||
"SubTypeNone",
|
"location": {
|
||||||
"SubTypeSensorTemp",
|
"type": "string"
|
||||||
"SubTypeSensorHumidity",
|
|
||||||
"SubTypeSensorAmmonia",
|
|
||||||
"SubTypeSensorWeight",
|
|
||||||
"SubTypeValveFeed",
|
|
||||||
"SubTypeFan",
|
|
||||||
"SubTypeWaterCurtain"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"models.DeviceType": {
|
"name": {
|
||||||
"type": "string",
|
"type": "string"
|
||||||
"enum": [
|
},
|
||||||
"area_controller",
|
"network_id": {
|
||||||
"device"
|
"type": "string"
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"device.CreateDeviceRequest": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"area_controller_id",
|
||||||
|
"device_template_id",
|
||||||
|
"name"
|
||||||
],
|
],
|
||||||
"x-enum-varnames": [
|
"properties": {
|
||||||
"DeviceTypeAreaController",
|
"area_controller_id": {
|
||||||
"DeviceTypeDevice"
|
"type": "integer"
|
||||||
]
|
},
|
||||||
|
"device_template_id": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"location": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"device.UpdateAreaControllerRequest": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"name",
|
||||||
|
"network_id"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"location": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"network_id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"device.UpdateDeviceRequest": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"area_controller_id",
|
||||||
|
"device_template_id",
|
||||||
|
"name"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"area_controller_id": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"device_template_id": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"location": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"git_huangwc_com_pig_pig-farm-controller_internal_app_controller_device.DeviceResponse": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"area_controller_id": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"area_controller_name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"created_at": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"device_template_id": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"device_template_name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"location": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": true
|
||||||
|
},
|
||||||
|
"updated_at": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"models.PlanContentType": {
|
"models.PlanContentType": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
@@ -1075,16 +1420,24 @@ const docTemplate = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"user.LoginRequest": {
|
"user.HistoryResponse": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
|
||||||
"password",
|
|
||||||
"username"
|
|
||||||
],
|
|
||||||
"properties": {
|
"properties": {
|
||||||
"password": {
|
"action_type": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"example": "password123"
|
"example": "更新设备"
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "设备更新成功"
|
||||||
|
},
|
||||||
|
"target_resource": {},
|
||||||
|
"time": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"user_id": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 101
|
||||||
},
|
},
|
||||||
"username": {
|
"username": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
@@ -1092,6 +1445,39 @@ const docTemplate = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"user.ListHistoryResponse": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"history": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/user.HistoryResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"total": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 100
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"user.LoginRequest": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"identifier",
|
||||||
|
"password"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"identifier": {
|
||||||
|
"description": "Identifier 可以是用户名、邮箱、手机号、微信号或飞书账号",
|
||||||
|
"type": "string",
|
||||||
|
"example": "testuser"
|
||||||
|
},
|
||||||
|
"password": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "password123"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"user.LoginResponse": {
|
"user.LoginResponse": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|||||||
@@ -4,6 +4,204 @@
|
|||||||
"contact": {}
|
"contact": {}
|
||||||
},
|
},
|
||||||
"paths": {
|
"paths": {
|
||||||
|
"/api/v1/area-controllers": {
|
||||||
|
"get": {
|
||||||
|
"description": "获取系统中所有区域主控的列表",
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"区域主控管理"
|
||||||
|
],
|
||||||
|
"summary": "获取所有区域主控列表",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/controller.Response"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/device.AreaControllerResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"post": {
|
||||||
|
"description": "根据提供的信息创建一个新区域主控",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"区域主控管理"
|
||||||
|
],
|
||||||
|
"summary": "创建新区域主控",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "区域主控信息",
|
||||||
|
"name": "areaController",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/device.CreateAreaControllerRequest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/controller.Response"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"$ref": "#/definitions/device.AreaControllerResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/v1/area-controllers/{id}": {
|
||||||
|
"get": {
|
||||||
|
"description": "根据ID获取单个区域主控的详细信息",
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"区域主控管理"
|
||||||
|
],
|
||||||
|
"summary": "获取区域主控信息",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "区域主控ID",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/controller.Response"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"$ref": "#/definitions/device.AreaControllerResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"put": {
|
||||||
|
"description": "根据ID更新一个已存在的区域主控信息",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"区域主控管理"
|
||||||
|
],
|
||||||
|
"summary": "更新区域主控信息",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "区域主控ID",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "要更新的区域主控信息",
|
||||||
|
"name": "areaController",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/device.UpdateAreaControllerRequest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/controller.Response"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"$ref": "#/definitions/device.AreaControllerResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"delete": {
|
||||||
|
"description": "根据ID删除一个区域主控(软删除)",
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"区域主控管理"
|
||||||
|
],
|
||||||
|
"summary": "删除区域主控",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "区域主控ID",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "OK",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/controller.Response"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/api/v1/devices": {
|
"/api/v1/devices": {
|
||||||
"get": {
|
"get": {
|
||||||
"description": "获取系统中所有设备的列表",
|
"description": "获取系统中所有设备的列表",
|
||||||
@@ -370,7 +568,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"delete": {
|
"delete": {
|
||||||
"description": "根据计划ID删除计划。",
|
"description": "根据计划ID删除计划。(软删除)",
|
||||||
"produces": [
|
"produces": [
|
||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
@@ -503,7 +701,7 @@
|
|||||||
},
|
},
|
||||||
"/api/v1/users/login": {
|
"/api/v1/users/login": {
|
||||||
"post": {
|
"post": {
|
||||||
"description": "用户使用用户名和密码登录,成功后返回 JWT 令牌。",
|
"description": "用户可以使用用户名、邮箱、手机号、微信号或飞书账号进行登录,成功后返回 JWT 令牌。",
|
||||||
"consumes": [
|
"consumes": [
|
||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
@@ -546,6 +744,67 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"/api/v1/users/{id}/history": {
|
||||||
|
"get": {
|
||||||
|
"description": "根据用户ID,分页获取该用户的操作审计日志。",
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"用户管理"
|
||||||
|
],
|
||||||
|
"summary": "获取指定用户的操作历史",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"description": "用户ID",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"default": 1,
|
||||||
|
"description": "页码",
|
||||||
|
"name": "page",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "integer",
|
||||||
|
"default": 10,
|
||||||
|
"description": "每页大小",
|
||||||
|
"name": "page_size",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "按操作类型过滤",
|
||||||
|
"name": "action_type",
|
||||||
|
"in": "query"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "业务码为200代表成功获取",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/controller.Response"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"$ref": "#/definitions/user.ListHistoryResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"definitions": {
|
"definitions": {
|
||||||
@@ -554,7 +813,11 @@
|
|||||||
"properties": {
|
"properties": {
|
||||||
"code": {
|
"code": {
|
||||||
"description": "业务状态码",
|
"description": "业务状态码",
|
||||||
"type": "integer"
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/controller.ResponseCode"
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"data": {
|
"data": {
|
||||||
"description": "业务数据"
|
"description": "业务数据"
|
||||||
@@ -565,63 +828,50 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"device.CreateDeviceRequest": {
|
"controller.ResponseCode": {
|
||||||
"type": "object",
|
"type": "integer",
|
||||||
"required": [
|
"enum": [
|
||||||
"name",
|
2000,
|
||||||
"type"
|
2001,
|
||||||
|
4000,
|
||||||
|
4001,
|
||||||
|
4004,
|
||||||
|
4009,
|
||||||
|
5000,
|
||||||
|
5003
|
||||||
],
|
],
|
||||||
"properties": {
|
"x-enum-comments": {
|
||||||
"location": {
|
"CodeBadRequest": "请求参数错误",
|
||||||
"type": "string"
|
"CodeConflict": "资源冲突",
|
||||||
|
"CodeCreated": "创建成功",
|
||||||
|
"CodeInternalError": "服务器内部错误",
|
||||||
|
"CodeNotFound": "资源未找到",
|
||||||
|
"CodeServiceUnavailable": "服务不可用",
|
||||||
|
"CodeSuccess": "操作成功",
|
||||||
|
"CodeUnauthorized": "未授权"
|
||||||
},
|
},
|
||||||
"name": {
|
"x-enum-descriptions": [
|
||||||
"type": "string"
|
"操作成功",
|
||||||
},
|
"创建成功",
|
||||||
"parent_id": {
|
"请求参数错误",
|
||||||
"type": "integer"
|
"未授权",
|
||||||
},
|
"资源未找到",
|
||||||
"properties": {
|
"资源冲突",
|
||||||
"type": "object",
|
"服务器内部错误",
|
||||||
"additionalProperties": true
|
"服务不可用"
|
||||||
},
|
|
||||||
"sub_type": {
|
|
||||||
"$ref": "#/definitions/models.DeviceSubType"
|
|
||||||
},
|
|
||||||
"type": {
|
|
||||||
"$ref": "#/definitions/models.DeviceType"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"device.UpdateDeviceRequest": {
|
|
||||||
"type": "object",
|
|
||||||
"required": [
|
|
||||||
"name",
|
|
||||||
"type"
|
|
||||||
],
|
],
|
||||||
"properties": {
|
"x-enum-varnames": [
|
||||||
"location": {
|
"CodeSuccess",
|
||||||
"type": "string"
|
"CodeCreated",
|
||||||
|
"CodeBadRequest",
|
||||||
|
"CodeUnauthorized",
|
||||||
|
"CodeNotFound",
|
||||||
|
"CodeConflict",
|
||||||
|
"CodeInternalError",
|
||||||
|
"CodeServiceUnavailable"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"name": {
|
"device.AreaControllerResponse": {
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"parent_id": {
|
|
||||||
"type": "integer"
|
|
||||||
},
|
|
||||||
"properties": {
|
|
||||||
"type": "object",
|
|
||||||
"additionalProperties": true
|
|
||||||
},
|
|
||||||
"sub_type": {
|
|
||||||
"$ref": "#/definitions/models.DeviceSubType"
|
|
||||||
},
|
|
||||||
"type": {
|
|
||||||
"$ref": "#/definitions/models.DeviceType"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"git_huangwc_com_pig_pig-farm-controller_internal_app_controller_device.DeviceResponse": {
|
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"created_at": {
|
"created_at": {
|
||||||
@@ -636,57 +886,152 @@
|
|||||||
"name": {
|
"name": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"parent_id": {
|
"network_id": {
|
||||||
"type": "integer"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"properties": {
|
"properties": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"additionalProperties": true
|
"additionalProperties": true
|
||||||
},
|
},
|
||||||
"sub_type": {
|
"status": {
|
||||||
"$ref": "#/definitions/models.DeviceSubType"
|
"type": "string"
|
||||||
},
|
|
||||||
"type": {
|
|
||||||
"$ref": "#/definitions/models.DeviceType"
|
|
||||||
},
|
},
|
||||||
"updated_at": {
|
"updated_at": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"models.DeviceSubType": {
|
"device.CreateAreaControllerRequest": {
|
||||||
"type": "string",
|
"type": "object",
|
||||||
"enum": [
|
"required": [
|
||||||
"",
|
"name",
|
||||||
"temperature",
|
"network_id"
|
||||||
"humidity",
|
|
||||||
"ammonia",
|
|
||||||
"weight",
|
|
||||||
"feed_valve",
|
|
||||||
"fan",
|
|
||||||
"water_curtain"
|
|
||||||
],
|
],
|
||||||
"x-enum-varnames": [
|
"properties": {
|
||||||
"SubTypeNone",
|
"location": {
|
||||||
"SubTypeSensorTemp",
|
"type": "string"
|
||||||
"SubTypeSensorHumidity",
|
|
||||||
"SubTypeSensorAmmonia",
|
|
||||||
"SubTypeSensorWeight",
|
|
||||||
"SubTypeValveFeed",
|
|
||||||
"SubTypeFan",
|
|
||||||
"SubTypeWaterCurtain"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"models.DeviceType": {
|
"name": {
|
||||||
"type": "string",
|
"type": "string"
|
||||||
"enum": [
|
},
|
||||||
"area_controller",
|
"network_id": {
|
||||||
"device"
|
"type": "string"
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"device.CreateDeviceRequest": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"area_controller_id",
|
||||||
|
"device_template_id",
|
||||||
|
"name"
|
||||||
],
|
],
|
||||||
"x-enum-varnames": [
|
"properties": {
|
||||||
"DeviceTypeAreaController",
|
"area_controller_id": {
|
||||||
"DeviceTypeDevice"
|
"type": "integer"
|
||||||
]
|
},
|
||||||
|
"device_template_id": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"location": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"device.UpdateAreaControllerRequest": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"name",
|
||||||
|
"network_id"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"location": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"network_id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"device.UpdateDeviceRequest": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"area_controller_id",
|
||||||
|
"device_template_id",
|
||||||
|
"name"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"area_controller_id": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"device_template_id": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"location": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"git_huangwc_com_pig_pig-farm-controller_internal_app_controller_device.DeviceResponse": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"area_controller_id": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"area_controller_name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"created_at": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"device_template_id": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"device_template_name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"id": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"location": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": true
|
||||||
|
},
|
||||||
|
"updated_at": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"models.PlanContentType": {
|
"models.PlanContentType": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
@@ -1064,16 +1409,24 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"user.LoginRequest": {
|
"user.HistoryResponse": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
|
||||||
"password",
|
|
||||||
"username"
|
|
||||||
],
|
|
||||||
"properties": {
|
"properties": {
|
||||||
"password": {
|
"action_type": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"example": "password123"
|
"example": "更新设备"
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "设备更新成功"
|
||||||
|
},
|
||||||
|
"target_resource": {},
|
||||||
|
"time": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"user_id": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 101
|
||||||
},
|
},
|
||||||
"username": {
|
"username": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
@@ -1081,6 +1434,39 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"user.ListHistoryResponse": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"history": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/user.HistoryResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"total": {
|
||||||
|
"type": "integer",
|
||||||
|
"example": 100
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"user.LoginRequest": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"identifier",
|
||||||
|
"password"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"identifier": {
|
||||||
|
"description": "Identifier 可以是用户名、邮箱、手机号、微信号或飞书账号",
|
||||||
|
"type": "string",
|
||||||
|
"example": "testuser"
|
||||||
|
},
|
||||||
|
"password": {
|
||||||
|
"type": "string",
|
||||||
|
"example": "password123"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"user.LoginResponse": {
|
"user.LoginResponse": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|||||||
@@ -2,53 +2,54 @@ definitions:
|
|||||||
controller.Response:
|
controller.Response:
|
||||||
properties:
|
properties:
|
||||||
code:
|
code:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/definitions/controller.ResponseCode'
|
||||||
description: 业务状态码
|
description: 业务状态码
|
||||||
type: integer
|
|
||||||
data:
|
data:
|
||||||
description: 业务数据
|
description: 业务数据
|
||||||
message:
|
message:
|
||||||
description: 提示信息
|
description: 提示信息
|
||||||
type: string
|
type: string
|
||||||
type: object
|
type: object
|
||||||
device.CreateDeviceRequest:
|
controller.ResponseCode:
|
||||||
properties:
|
enum:
|
||||||
location:
|
- 2000
|
||||||
type: string
|
- 2001
|
||||||
name:
|
- 4000
|
||||||
type: string
|
- 4001
|
||||||
parent_id:
|
- 4004
|
||||||
|
- 4009
|
||||||
|
- 5000
|
||||||
|
- 5003
|
||||||
type: integer
|
type: integer
|
||||||
properties:
|
x-enum-comments:
|
||||||
additionalProperties: true
|
CodeBadRequest: 请求参数错误
|
||||||
type: object
|
CodeConflict: 资源冲突
|
||||||
sub_type:
|
CodeCreated: 创建成功
|
||||||
$ref: '#/definitions/models.DeviceSubType'
|
CodeInternalError: 服务器内部错误
|
||||||
type:
|
CodeNotFound: 资源未找到
|
||||||
$ref: '#/definitions/models.DeviceType'
|
CodeServiceUnavailable: 服务不可用
|
||||||
required:
|
CodeSuccess: 操作成功
|
||||||
- name
|
CodeUnauthorized: 未授权
|
||||||
- type
|
x-enum-descriptions:
|
||||||
type: object
|
- 操作成功
|
||||||
device.UpdateDeviceRequest:
|
- 创建成功
|
||||||
properties:
|
- 请求参数错误
|
||||||
location:
|
- 未授权
|
||||||
type: string
|
- 资源未找到
|
||||||
name:
|
- 资源冲突
|
||||||
type: string
|
- 服务器内部错误
|
||||||
parent_id:
|
- 服务不可用
|
||||||
type: integer
|
x-enum-varnames:
|
||||||
properties:
|
- CodeSuccess
|
||||||
additionalProperties: true
|
- CodeCreated
|
||||||
type: object
|
- CodeBadRequest
|
||||||
sub_type:
|
- CodeUnauthorized
|
||||||
$ref: '#/definitions/models.DeviceSubType'
|
- CodeNotFound
|
||||||
type:
|
- CodeConflict
|
||||||
$ref: '#/definitions/models.DeviceType'
|
- CodeInternalError
|
||||||
required:
|
- CodeServiceUnavailable
|
||||||
- name
|
device.AreaControllerResponse:
|
||||||
- type
|
|
||||||
type: object
|
|
||||||
git_huangwc_com_pig_pig-farm-controller_internal_app_controller_device.DeviceResponse:
|
|
||||||
properties:
|
properties:
|
||||||
created_at:
|
created_at:
|
||||||
type: string
|
type: string
|
||||||
@@ -58,46 +59,106 @@ definitions:
|
|||||||
type: string
|
type: string
|
||||||
name:
|
name:
|
||||||
type: string
|
type: string
|
||||||
parent_id:
|
network_id:
|
||||||
type: integer
|
type: string
|
||||||
properties:
|
properties:
|
||||||
additionalProperties: true
|
additionalProperties: true
|
||||||
type: object
|
type: object
|
||||||
sub_type:
|
status:
|
||||||
$ref: '#/definitions/models.DeviceSubType'
|
type: string
|
||||||
type:
|
|
||||||
$ref: '#/definitions/models.DeviceType'
|
|
||||||
updated_at:
|
updated_at:
|
||||||
type: string
|
type: string
|
||||||
type: object
|
type: object
|
||||||
models.DeviceSubType:
|
device.CreateAreaControllerRequest:
|
||||||
enum:
|
properties:
|
||||||
- ""
|
location:
|
||||||
- temperature
|
|
||||||
- humidity
|
|
||||||
- ammonia
|
|
||||||
- weight
|
|
||||||
- feed_valve
|
|
||||||
- fan
|
|
||||||
- water_curtain
|
|
||||||
type: string
|
type: string
|
||||||
x-enum-varnames:
|
name:
|
||||||
- SubTypeNone
|
|
||||||
- SubTypeSensorTemp
|
|
||||||
- SubTypeSensorHumidity
|
|
||||||
- SubTypeSensorAmmonia
|
|
||||||
- SubTypeSensorWeight
|
|
||||||
- SubTypeValveFeed
|
|
||||||
- SubTypeFan
|
|
||||||
- SubTypeWaterCurtain
|
|
||||||
models.DeviceType:
|
|
||||||
enum:
|
|
||||||
- area_controller
|
|
||||||
- device
|
|
||||||
type: string
|
type: string
|
||||||
x-enum-varnames:
|
network_id:
|
||||||
- DeviceTypeAreaController
|
type: string
|
||||||
- DeviceTypeDevice
|
properties:
|
||||||
|
additionalProperties: true
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- name
|
||||||
|
- network_id
|
||||||
|
type: object
|
||||||
|
device.CreateDeviceRequest:
|
||||||
|
properties:
|
||||||
|
area_controller_id:
|
||||||
|
type: integer
|
||||||
|
device_template_id:
|
||||||
|
type: integer
|
||||||
|
location:
|
||||||
|
type: string
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
properties:
|
||||||
|
additionalProperties: true
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- area_controller_id
|
||||||
|
- device_template_id
|
||||||
|
- name
|
||||||
|
type: object
|
||||||
|
device.UpdateAreaControllerRequest:
|
||||||
|
properties:
|
||||||
|
location:
|
||||||
|
type: string
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
network_id:
|
||||||
|
type: string
|
||||||
|
properties:
|
||||||
|
additionalProperties: true
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- name
|
||||||
|
- network_id
|
||||||
|
type: object
|
||||||
|
device.UpdateDeviceRequest:
|
||||||
|
properties:
|
||||||
|
area_controller_id:
|
||||||
|
type: integer
|
||||||
|
device_template_id:
|
||||||
|
type: integer
|
||||||
|
location:
|
||||||
|
type: string
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
properties:
|
||||||
|
additionalProperties: true
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- area_controller_id
|
||||||
|
- device_template_id
|
||||||
|
- name
|
||||||
|
type: object
|
||||||
|
git_huangwc_com_pig_pig-farm-controller_internal_app_controller_device.DeviceResponse:
|
||||||
|
properties:
|
||||||
|
area_controller_id:
|
||||||
|
type: integer
|
||||||
|
area_controller_name:
|
||||||
|
type: string
|
||||||
|
created_at:
|
||||||
|
type: string
|
||||||
|
device_template_id:
|
||||||
|
type: integer
|
||||||
|
device_template_name:
|
||||||
|
type: string
|
||||||
|
id:
|
||||||
|
type: integer
|
||||||
|
location:
|
||||||
|
type: string
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
properties:
|
||||||
|
additionalProperties: true
|
||||||
|
type: object
|
||||||
|
updated_at:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
models.PlanContentType:
|
models.PlanContentType:
|
||||||
enum:
|
enum:
|
||||||
- sub_plans
|
- sub_plans
|
||||||
@@ -358,17 +419,46 @@ definitions:
|
|||||||
example: newuser
|
example: newuser
|
||||||
type: string
|
type: string
|
||||||
type: object
|
type: object
|
||||||
user.LoginRequest:
|
user.HistoryResponse:
|
||||||
properties:
|
properties:
|
||||||
password:
|
action_type:
|
||||||
example: password123
|
example: 更新设备
|
||||||
type: string
|
type: string
|
||||||
|
description:
|
||||||
|
example: 设备更新成功
|
||||||
|
type: string
|
||||||
|
target_resource: {}
|
||||||
|
time:
|
||||||
|
type: string
|
||||||
|
user_id:
|
||||||
|
example: 101
|
||||||
|
type: integer
|
||||||
username:
|
username:
|
||||||
example: testuser
|
example: testuser
|
||||||
type: string
|
type: string
|
||||||
|
type: object
|
||||||
|
user.ListHistoryResponse:
|
||||||
|
properties:
|
||||||
|
history:
|
||||||
|
items:
|
||||||
|
$ref: '#/definitions/user.HistoryResponse'
|
||||||
|
type: array
|
||||||
|
total:
|
||||||
|
example: 100
|
||||||
|
type: integer
|
||||||
|
type: object
|
||||||
|
user.LoginRequest:
|
||||||
|
properties:
|
||||||
|
identifier:
|
||||||
|
description: Identifier 可以是用户名、邮箱、手机号、微信号或飞书账号
|
||||||
|
example: testuser
|
||||||
|
type: string
|
||||||
|
password:
|
||||||
|
example: password123
|
||||||
|
type: string
|
||||||
required:
|
required:
|
||||||
|
- identifier
|
||||||
- password
|
- password
|
||||||
- username
|
|
||||||
type: object
|
type: object
|
||||||
user.LoginResponse:
|
user.LoginResponse:
|
||||||
properties:
|
properties:
|
||||||
@@ -385,6 +475,125 @@ definitions:
|
|||||||
info:
|
info:
|
||||||
contact: {}
|
contact: {}
|
||||||
paths:
|
paths:
|
||||||
|
/api/v1/area-controllers:
|
||||||
|
get:
|
||||||
|
description: 获取系统中所有区域主控的列表
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/definitions/controller.Response'
|
||||||
|
- properties:
|
||||||
|
data:
|
||||||
|
items:
|
||||||
|
$ref: '#/definitions/device.AreaControllerResponse'
|
||||||
|
type: array
|
||||||
|
type: object
|
||||||
|
summary: 获取所有区域主控列表
|
||||||
|
tags:
|
||||||
|
- 区域主控管理
|
||||||
|
post:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: 根据提供的信息创建一个新区域主控
|
||||||
|
parameters:
|
||||||
|
- description: 区域主控信息
|
||||||
|
in: body
|
||||||
|
name: areaController
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/device.CreateAreaControllerRequest'
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/definitions/controller.Response'
|
||||||
|
- properties:
|
||||||
|
data:
|
||||||
|
$ref: '#/definitions/device.AreaControllerResponse'
|
||||||
|
type: object
|
||||||
|
summary: 创建新区域主控
|
||||||
|
tags:
|
||||||
|
- 区域主控管理
|
||||||
|
/api/v1/area-controllers/{id}:
|
||||||
|
delete:
|
||||||
|
description: 根据ID删除一个区域主控(软删除)
|
||||||
|
parameters:
|
||||||
|
- description: 区域主控ID
|
||||||
|
in: path
|
||||||
|
name: id
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/controller.Response'
|
||||||
|
summary: 删除区域主控
|
||||||
|
tags:
|
||||||
|
- 区域主控管理
|
||||||
|
get:
|
||||||
|
description: 根据ID获取单个区域主控的详细信息
|
||||||
|
parameters:
|
||||||
|
- description: 区域主控ID
|
||||||
|
in: path
|
||||||
|
name: id
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/definitions/controller.Response'
|
||||||
|
- properties:
|
||||||
|
data:
|
||||||
|
$ref: '#/definitions/device.AreaControllerResponse'
|
||||||
|
type: object
|
||||||
|
summary: 获取区域主控信息
|
||||||
|
tags:
|
||||||
|
- 区域主控管理
|
||||||
|
put:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: 根据ID更新一个已存在的区域主控信息
|
||||||
|
parameters:
|
||||||
|
- description: 区域主控ID
|
||||||
|
in: path
|
||||||
|
name: id
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
- description: 要更新的区域主控信息
|
||||||
|
in: body
|
||||||
|
name: areaController
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/device.UpdateAreaControllerRequest'
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: OK
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/definitions/controller.Response'
|
||||||
|
- properties:
|
||||||
|
data:
|
||||||
|
$ref: '#/definitions/device.AreaControllerResponse'
|
||||||
|
type: object
|
||||||
|
summary: 更新区域主控信息
|
||||||
|
tags:
|
||||||
|
- 区域主控管理
|
||||||
/api/v1/devices:
|
/api/v1/devices:
|
||||||
get:
|
get:
|
||||||
description: 获取系统中所有设备的列表
|
description: 获取系统中所有设备的列表
|
||||||
@@ -550,7 +759,7 @@ paths:
|
|||||||
- 计划管理
|
- 计划管理
|
||||||
/api/v1/plans/{id}:
|
/api/v1/plans/{id}:
|
||||||
delete:
|
delete:
|
||||||
description: 根据计划ID删除计划。
|
description: 根据计划ID删除计划。(软删除)
|
||||||
parameters:
|
parameters:
|
||||||
- description: 计划ID
|
- description: 计划ID
|
||||||
in: path
|
in: path
|
||||||
@@ -686,11 +895,49 @@ paths:
|
|||||||
summary: 创建新用户
|
summary: 创建新用户
|
||||||
tags:
|
tags:
|
||||||
- 用户管理
|
- 用户管理
|
||||||
|
/api/v1/users/{id}/history:
|
||||||
|
get:
|
||||||
|
description: 根据用户ID,分页获取该用户的操作审计日志。
|
||||||
|
parameters:
|
||||||
|
- description: 用户ID
|
||||||
|
in: path
|
||||||
|
name: id
|
||||||
|
required: true
|
||||||
|
type: integer
|
||||||
|
- default: 1
|
||||||
|
description: 页码
|
||||||
|
in: query
|
||||||
|
name: page
|
||||||
|
type: integer
|
||||||
|
- default: 10
|
||||||
|
description: 每页大小
|
||||||
|
in: query
|
||||||
|
name: page_size
|
||||||
|
type: integer
|
||||||
|
- description: 按操作类型过滤
|
||||||
|
in: query
|
||||||
|
name: action_type
|
||||||
|
type: string
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: 业务码为200代表成功获取
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/definitions/controller.Response'
|
||||||
|
- properties:
|
||||||
|
data:
|
||||||
|
$ref: '#/definitions/user.ListHistoryResponse'
|
||||||
|
type: object
|
||||||
|
summary: 获取指定用户的操作历史
|
||||||
|
tags:
|
||||||
|
- 用户管理
|
||||||
/api/v1/users/login:
|
/api/v1/users/login:
|
||||||
post:
|
post:
|
||||||
consumes:
|
consumes:
|
||||||
- application/json
|
- application/json
|
||||||
description: 用户使用用户名和密码登录,成功后返回 JWT 令牌。
|
description: 用户可以使用用户名、邮箱、手机号、微信号或飞书账号进行登录,成功后返回 JWT 令牌。
|
||||||
parameters:
|
parameters:
|
||||||
- description: 登录凭证
|
- description: 登录凭证
|
||||||
in: body
|
in: body
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ func NewAPI(cfg config.ServerConfig,
|
|||||||
logger *logs.Logger,
|
logger *logs.Logger,
|
||||||
userRepo repository.UserRepository,
|
userRepo repository.UserRepository,
|
||||||
deviceRepository repository.DeviceRepository,
|
deviceRepository repository.DeviceRepository,
|
||||||
|
areaControllerRepository repository.AreaControllerRepository,
|
||||||
planRepository repository.PlanRepository,
|
planRepository repository.PlanRepository,
|
||||||
userActionLogRepository repository.UserActionLogRepository,
|
userActionLogRepository repository.UserActionLogRepository,
|
||||||
tokenService token.TokenService,
|
tokenService token.TokenService,
|
||||||
@@ -85,7 +86,7 @@ func NewAPI(cfg config.ServerConfig,
|
|||||||
// 在 NewAPI 中初始化用户控制器,并将其作为 API 结构体的成员
|
// 在 NewAPI 中初始化用户控制器,并将其作为 API 结构体的成员
|
||||||
userController: user.NewController(userRepo, userActionLogRepository, logger, tokenService),
|
userController: user.NewController(userRepo, userActionLogRepository, logger, tokenService),
|
||||||
// 在 NewAPI 中初始化设备控制器,并将其作为 API 结构体的成员
|
// 在 NewAPI 中初始化设备控制器,并将其作为 API 结构体的成员
|
||||||
deviceController: device.NewController(deviceRepository, logger),
|
deviceController: device.NewController(deviceRepository, areaControllerRepository, logger),
|
||||||
// 在 NewAPI 中初始化计划控制器,并将其作为 API 结构体的成员
|
// 在 NewAPI 中初始化计划控制器,并将其作为 API 结构体的成员
|
||||||
planController: plan.NewController(logger, planRepository, analysisTaskManager),
|
planController: plan.NewController(logger, planRepository, analysisTaskManager),
|
||||||
}
|
}
|
||||||
@@ -159,6 +160,17 @@ func (a *API) setupRoutes() {
|
|||||||
}
|
}
|
||||||
a.logger.Info("设备相关接口注册成功 (需要认证和审计)")
|
a.logger.Info("设备相关接口注册成功 (需要认证和审计)")
|
||||||
|
|
||||||
|
// 区域主控相关路由组
|
||||||
|
areaControllerGroup := authGroup.Group("/area-controllers")
|
||||||
|
{
|
||||||
|
areaControllerGroup.POST("", a.deviceController.CreateAreaController)
|
||||||
|
areaControllerGroup.GET("", a.deviceController.ListAreaControllers)
|
||||||
|
areaControllerGroup.GET("/:id", a.deviceController.GetAreaController)
|
||||||
|
areaControllerGroup.PUT("/:id", a.deviceController.UpdateAreaController)
|
||||||
|
areaControllerGroup.DELETE("/:id", a.deviceController.DeleteAreaController)
|
||||||
|
}
|
||||||
|
a.logger.Info("区域主控相关接口注册成功 (需要认证和审计)")
|
||||||
|
|
||||||
// 计划相关路由组
|
// 计划相关路由组
|
||||||
planGroup := authGroup.Group("/plans")
|
planGroup := authGroup.Group("/plans")
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -16,16 +16,22 @@ import (
|
|||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Controller 设备控制器,封装了所有与设备相关的业务逻辑
|
// Controller 设备控制器,封装了所有与设备和区域主控相关的业务逻辑
|
||||||
type Controller struct {
|
type Controller struct {
|
||||||
repo repository.DeviceRepository
|
deviceRepo repository.DeviceRepository
|
||||||
|
areaControllerRepo repository.AreaControllerRepository
|
||||||
logger *logs.Logger
|
logger *logs.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewController 创建一个新的设备控制器实例
|
// NewController 创建一个新的设备控制器实例
|
||||||
func NewController(repo repository.DeviceRepository, logger *logs.Logger) *Controller {
|
func NewController(
|
||||||
|
deviceRepo repository.DeviceRepository,
|
||||||
|
areaControllerRepo repository.AreaControllerRepository,
|
||||||
|
logger *logs.Logger,
|
||||||
|
) *Controller {
|
||||||
return &Controller{
|
return &Controller{
|
||||||
repo: repo,
|
deviceRepo: deviceRepo,
|
||||||
|
areaControllerRepo: areaControllerRepo,
|
||||||
logger: logger,
|
logger: logger,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -50,6 +56,22 @@ type UpdateDeviceRequest struct {
|
|||||||
Properties map[string]interface{} `json:"properties,omitempty"`
|
Properties map[string]interface{} `json:"properties,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreateAreaControllerRequest 定义了创建区域主控时需要传入的参数
|
||||||
|
type CreateAreaControllerRequest struct {
|
||||||
|
Name string `json:"name" binding:"required"`
|
||||||
|
NetworkID string `json:"network_id" binding:"required"`
|
||||||
|
Location string `json:"location,omitempty"`
|
||||||
|
Properties map[string]interface{} `json:"properties,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateAreaControllerRequest 定义了更新区域主控时需要传入的参数
|
||||||
|
type UpdateAreaControllerRequest struct {
|
||||||
|
Name string `json:"name" binding:"required"`
|
||||||
|
NetworkID string `json:"network_id" binding:"required"`
|
||||||
|
Location string `json:"location,omitempty"`
|
||||||
|
Properties map[string]interface{} `json:"properties,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
// --- Response DTOs ---
|
// --- Response DTOs ---
|
||||||
|
|
||||||
// DeviceResponse 定义了返回给客户端的单个设备信息的结构
|
// DeviceResponse 定义了返回给客户端的单个设备信息的结构
|
||||||
@@ -66,6 +88,18 @@ type DeviceResponse struct {
|
|||||||
UpdatedAt string `json:"updated_at"`
|
UpdatedAt string `json:"updated_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AreaControllerResponse 定义了返回给客户端的单个区域主控信息的结构
|
||||||
|
type AreaControllerResponse struct {
|
||||||
|
ID uint `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
NetworkID string `json:"network_id"`
|
||||||
|
Location string `json:"location"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
Properties map[string]interface{} `json:"properties"`
|
||||||
|
CreatedAt string `json:"created_at"`
|
||||||
|
UpdatedAt string `json:"updated_at"`
|
||||||
|
}
|
||||||
|
|
||||||
// --- DTO 转换函数 ---
|
// --- DTO 转换函数 ---
|
||||||
|
|
||||||
// newDeviceResponse 从数据库模型创建一个新的设备响应 DTO
|
// newDeviceResponse 从数据库模型创建一个新的设备响应 DTO
|
||||||
@@ -119,7 +153,45 @@ func newListDeviceResponse(devices []*models.Device) ([]*DeviceResponse, error)
|
|||||||
return list, nil
|
return list, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Controller Methods ---
|
// newAreaControllerResponse 从数据库模型创建一个新的区域主控响应 DTO
|
||||||
|
func newAreaControllerResponse(ac *models.AreaController) (*AreaControllerResponse, error) {
|
||||||
|
if ac == nil {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var props map[string]interface{}
|
||||||
|
if len(ac.Properties) > 0 && string(ac.Properties) != "null" {
|
||||||
|
if err := json.Unmarshal(ac.Properties, &props); err != nil {
|
||||||
|
return nil, fmt.Errorf("解析区域主控属性失败 (ID: %d): %w", ac.ID, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &AreaControllerResponse{
|
||||||
|
ID: ac.ID,
|
||||||
|
Name: ac.Name,
|
||||||
|
NetworkID: ac.NetworkID,
|
||||||
|
Location: ac.Location,
|
||||||
|
Status: ac.Status,
|
||||||
|
Properties: props,
|
||||||
|
CreatedAt: ac.CreatedAt.Format(time.RFC3339),
|
||||||
|
UpdatedAt: ac.UpdatedAt.Format(time.RFC3339),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// newListAreaControllerResponse 从数据库模型切片创建一个新的区域主控列表响应 DTO 切片
|
||||||
|
func newListAreaControllerResponse(acs []*models.AreaController) ([]*AreaControllerResponse, error) {
|
||||||
|
list := make([]*AreaControllerResponse, 0, len(acs))
|
||||||
|
for _, ac := range acs {
|
||||||
|
resp, err := newAreaControllerResponse(ac)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
list = append(list, resp)
|
||||||
|
}
|
||||||
|
return list, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Controller Methods: Devices ---
|
||||||
|
|
||||||
// CreateDevice godoc
|
// CreateDevice godoc
|
||||||
// @Summary 创建新设备
|
// @Summary 创建新设备
|
||||||
@@ -154,25 +226,19 @@ func (c *Controller) CreateDevice(ctx *gin.Context) {
|
|||||||
Properties: propertiesJSON,
|
Properties: propertiesJSON,
|
||||||
}
|
}
|
||||||
|
|
||||||
// 在创建设备前进行自检
|
|
||||||
// 注意:这里的 SelfCheck 依赖于 DeviceTemplate 和 AreaController 字段,
|
|
||||||
// 但在创建时这些关联对象可能尚未完全加载。如果 SelfCheck 内部需要这些关联对象,
|
|
||||||
// 则需要在调用 SelfCheck 之前手动加载或调整 SelfCheck 逻辑。
|
|
||||||
// 目前假设 SelfCheck 仅检查 ID 和 Properties。
|
|
||||||
if err := device.SelfCheck(); err != nil {
|
if err := device.SelfCheck(); err != nil {
|
||||||
c.logger.Errorf("%s: 设备属性自检失败: %v", actionType, err)
|
c.logger.Errorf("%s: 设备属性自检失败: %v", actionType, err)
|
||||||
controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "设备属性不符合要求: "+err.Error(), actionType, "设备属性自检失败", device)
|
controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "设备属性不符合要求: "+err.Error(), actionType, "设备属性自检失败", device)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := c.repo.Create(device); err != nil {
|
if err := c.deviceRepo.Create(device); err != nil {
|
||||||
c.logger.Errorf("%s: 数据库操作失败: %v", actionType, err)
|
c.logger.Errorf("%s: 数据库操作失败: %v", actionType, err)
|
||||||
controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "创建设备失败: "+err.Error(), actionType, "数据库创建失败", device)
|
controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "创建设备失败: "+err.Error(), actionType, "数据库创建失败", device)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 为了在响应中包含 DeviceTemplateName 和 AreaControllerName,需要重新从数据库加载设备,并预加载关联。
|
createdDevice, err := c.deviceRepo.FindByID(device.ID)
|
||||||
createdDevice, err := c.repo.FindByID(device.ID)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.logger.Errorf("%s: 重新加载创建的设备失败: %v", actionType, err)
|
c.logger.Errorf("%s: 重新加载创建的设备失败: %v", actionType, err)
|
||||||
controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "设备创建成功,但重新加载设备失败", actionType, "重新加载设备失败", device)
|
controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "设备创建成功,但重新加载设备失败", actionType, "重新加载设备失败", device)
|
||||||
@@ -208,8 +274,7 @@ func (c *Controller) GetDevice(ctx *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 假设 FindByIDString 方法会预加载 DeviceTemplate 和 AreaController
|
device, err := c.deviceRepo.FindByIDString(deviceID)
|
||||||
device, err := c.repo.FindByIDString(deviceID)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
c.logger.Warnf("%s: 设备不存在, ID: %s", actionType, deviceID)
|
c.logger.Warnf("%s: 设备不存在, ID: %s", actionType, deviceID)
|
||||||
@@ -246,8 +311,7 @@ func (c *Controller) GetDevice(ctx *gin.Context) {
|
|||||||
// @Router /api/v1/devices [get]
|
// @Router /api/v1/devices [get]
|
||||||
func (c *Controller) ListDevices(ctx *gin.Context) {
|
func (c *Controller) ListDevices(ctx *gin.Context) {
|
||||||
const actionType = "获取设备列表"
|
const actionType = "获取设备列表"
|
||||||
// 假设 ListAll 方法会预加载 DeviceTemplate 和 AreaController
|
devices, err := c.deviceRepo.ListAll()
|
||||||
devices, err := c.repo.ListAll()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.logger.Errorf("%s: 数据库查询失败: %v", actionType, err)
|
c.logger.Errorf("%s: 数据库查询失败: %v", actionType, err)
|
||||||
controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取设备列表失败: "+err.Error(), actionType, "数据库查询失败", nil)
|
controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取设备列表失败: "+err.Error(), actionType, "数据库查询失败", nil)
|
||||||
@@ -279,9 +343,7 @@ func (c *Controller) UpdateDevice(ctx *gin.Context) {
|
|||||||
const actionType = "更新设备"
|
const actionType = "更新设备"
|
||||||
deviceID := ctx.Param("id")
|
deviceID := ctx.Param("id")
|
||||||
|
|
||||||
// 1. 检查设备是否存在
|
existingDevice, err := c.deviceRepo.FindByIDString(deviceID)
|
||||||
// 假设 FindByIDString 方法会预加载 DeviceTemplate 和 AreaController
|
|
||||||
existingDevice, err := c.repo.FindByIDString(deviceID)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
c.logger.Warnf("%s: 设备不存在, ID: %s", actionType, deviceID)
|
c.logger.Warnf("%s: 设备不存在, ID: %s", actionType, deviceID)
|
||||||
@@ -298,7 +360,6 @@ func (c *Controller) UpdateDevice(ctx *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 绑定请求参数
|
|
||||||
var req UpdateDeviceRequest
|
var req UpdateDeviceRequest
|
||||||
if err := ctx.ShouldBindJSON(&req); err != nil {
|
if err := ctx.ShouldBindJSON(&req); err != nil {
|
||||||
c.logger.Errorf("%s: 参数绑定失败: %v", actionType, err)
|
c.logger.Errorf("%s: 参数绑定失败: %v", actionType, err)
|
||||||
@@ -313,33 +374,25 @@ func (c *Controller) UpdateDevice(ctx *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. 更新从数据库中查出的现有设备对象的字段
|
|
||||||
existingDevice.Name = req.Name
|
existingDevice.Name = req.Name
|
||||||
existingDevice.DeviceTemplateID = req.DeviceTemplateID
|
existingDevice.DeviceTemplateID = req.DeviceTemplateID
|
||||||
existingDevice.AreaControllerID = req.AreaControllerID
|
existingDevice.AreaControllerID = req.AreaControllerID
|
||||||
existingDevice.Location = req.Location
|
existingDevice.Location = req.Location
|
||||||
existingDevice.Properties = propertiesJSON
|
existingDevice.Properties = propertiesJSON
|
||||||
|
|
||||||
// 在更新设备前进行自检
|
|
||||||
// 注意:这里的 SelfCheck 依赖于 DeviceTemplate 和 AreaController 字段,
|
|
||||||
// 但在更新时这些关联对象可能尚未完全加载。如果 SelfCheck 内部需要这些关联对象,
|
|
||||||
// 则需要在调用 SelfCheck 之前手动加载或调整 SelfCheck 逻辑。
|
|
||||||
// 目前假设 SelfCheck 仅检查 ID 和 Properties。
|
|
||||||
if err := existingDevice.SelfCheck(); err != nil {
|
if err := existingDevice.SelfCheck(); err != nil {
|
||||||
c.logger.Errorf("%s: 设备属性自检失败: %v", actionType, err)
|
c.logger.Errorf("%s: 设备属性自检失败: %v", actionType, err)
|
||||||
controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "设备属性不符合要求: "+err.Error(), actionType, "设备属性自检失败", existingDevice)
|
controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "设备属性不符合要求: "+err.Error(), actionType, "设备属性自检失败", existingDevice)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. 将修改后的 existingDevice 对象保存回数据库
|
if err := c.deviceRepo.Update(existingDevice); err != nil {
|
||||||
if err := c.repo.Update(existingDevice); err != nil {
|
|
||||||
c.logger.Errorf("%s: 数据库更新失败: %v, Device: %+v", actionType, err, existingDevice)
|
c.logger.Errorf("%s: 数据库更新失败: %v, Device: %+v", actionType, err, existingDevice)
|
||||||
controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "更新设备失败: "+err.Error(), actionType, "数据库更新失败", existingDevice)
|
controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "更新设备失败: "+err.Error(), actionType, "数据库更新失败", existingDevice)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 为了在响应中包含 DeviceTemplateName 和 AreaControllerName,需要重新从数据库加载设备,并预加载关联。
|
updatedDevice, err := c.deviceRepo.FindByID(existingDevice.ID)
|
||||||
updatedDevice, err := c.repo.FindByID(existingDevice.ID)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.logger.Errorf("%s: 重新加载更新的设备失败: %v", actionType, err)
|
c.logger.Errorf("%s: 重新加载更新的设备失败: %v", actionType, err)
|
||||||
controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "设备更新成功,但重新加载设备失败", actionType, "重新加载设备失败", existingDevice)
|
controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "设备更新成功,但重新加载设备失败", actionType, "重新加载设备失败", existingDevice)
|
||||||
@@ -369,7 +422,6 @@ func (c *Controller) DeleteDevice(ctx *gin.Context) {
|
|||||||
const actionType = "删除设备"
|
const actionType = "删除设备"
|
||||||
deviceID := ctx.Param("id")
|
deviceID := ctx.Param("id")
|
||||||
|
|
||||||
// 我们需要先将字符串ID转换为uint,因为Delete方法需要uint类型
|
|
||||||
idUint, err := strconv.ParseUint(deviceID, 10, 64)
|
idUint, err := strconv.ParseUint(deviceID, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.logger.Errorf("%s: 设备ID格式错误: %v, ID: %s", actionType, err, deviceID)
|
c.logger.Errorf("%s: 设备ID格式错误: %v, ID: %s", actionType, err, deviceID)
|
||||||
@@ -377,8 +429,7 @@ func (c *Controller) DeleteDevice(ctx *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查设备是否存在(可选,但通常在删除前会检查)
|
_, err = c.deviceRepo.FindByIDString(deviceID)
|
||||||
_, err = c.repo.FindByIDString(deviceID)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
c.logger.Warnf("%s: 设备不存在, ID: %s", actionType, deviceID)
|
c.logger.Warnf("%s: 设备不存在, ID: %s", actionType, deviceID)
|
||||||
@@ -390,7 +441,7 @@ func (c *Controller) DeleteDevice(ctx *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := c.repo.Delete(uint(idUint)); err != nil {
|
if err := c.deviceRepo.Delete(uint(idUint)); err != nil {
|
||||||
c.logger.Errorf("%s: 数据库删除失败: %v, ID: %d", actionType, err, idUint)
|
c.logger.Errorf("%s: 数据库删除失败: %v, ID: %d", actionType, err, idUint)
|
||||||
controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "删除设备失败: "+err.Error(), actionType, "数据库删除失败", deviceID)
|
controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "删除设备失败: "+err.Error(), actionType, "数据库删除失败", deviceID)
|
||||||
return
|
return
|
||||||
@@ -399,3 +450,245 @@ func (c *Controller) DeleteDevice(ctx *gin.Context) {
|
|||||||
c.logger.Infof("%s: 设备删除成功, ID: %d", actionType, idUint)
|
c.logger.Infof("%s: 设备删除成功, ID: %d", actionType, idUint)
|
||||||
controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "设备删除成功", nil, actionType, "设备删除成功", deviceID)
|
controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "设备删除成功", nil, actionType, "设备删除成功", deviceID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- Controller Methods: Area Controllers ---
|
||||||
|
|
||||||
|
// CreateAreaController godoc
|
||||||
|
// @Summary 创建新区域主控
|
||||||
|
// @Description 根据提供的信息创建一个新区域主控
|
||||||
|
// @Tags 区域主控管理
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param areaController body CreateAreaControllerRequest true "区域主控信息"
|
||||||
|
// @Success 200 {object} controller.Response{data=AreaControllerResponse}
|
||||||
|
// @Router /api/v1/area-controllers [post]
|
||||||
|
func (c *Controller) CreateAreaController(ctx *gin.Context) {
|
||||||
|
const actionType = "创建区域主控"
|
||||||
|
var req CreateAreaControllerRequest
|
||||||
|
if err := ctx.ShouldBindJSON(&req); err != nil {
|
||||||
|
c.logger.Errorf("%s: 参数绑定失败: %v", actionType, err)
|
||||||
|
controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的请求体: "+err.Error(), actionType, "请求体绑定失败", req)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
propertiesJSON, err := json.Marshal(req.Properties)
|
||||||
|
if err != nil {
|
||||||
|
c.logger.Errorf("%s: 序列化属性失败: %v", actionType, err)
|
||||||
|
controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "属性字段格式错误", actionType, "属性序列化失败", req.Properties)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ac := &models.AreaController{
|
||||||
|
Name: req.Name,
|
||||||
|
NetworkID: req.NetworkID,
|
||||||
|
Location: req.Location,
|
||||||
|
Properties: propertiesJSON,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := ac.SelfCheck(); err != nil {
|
||||||
|
c.logger.Errorf("%s: 区域主控自检失败: %v", actionType, err)
|
||||||
|
controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "区域主控参数不符合要求: "+err.Error(), actionType, "区域主控自检失败", ac)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := c.areaControllerRepo.Create(ac); err != nil {
|
||||||
|
c.logger.Errorf("%s: 数据库操作失败: %v", actionType, err)
|
||||||
|
controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "创建区域主控失败: "+err.Error(), actionType, "数据库创建失败", ac)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := newAreaControllerResponse(ac)
|
||||||
|
if err != nil {
|
||||||
|
c.logger.Errorf("%s: 序列化响应失败: %v", actionType, err)
|
||||||
|
controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "区域主控创建成功,但响应生成失败", actionType, "响应序列化失败", ac)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.logger.Infof("%s: 区域主控创建成功, ID: %d", actionType, ac.ID)
|
||||||
|
controller.SendSuccessWithAudit(ctx, controller.CodeCreated, "区域主控创建成功", resp, actionType, "区域主控创建成功", resp)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetAreaController godoc
|
||||||
|
// @Summary 获取区域主控信息
|
||||||
|
// @Description 根据ID获取单个区域主控的详细信息
|
||||||
|
// @Tags 区域主控管理
|
||||||
|
// @Produce json
|
||||||
|
// @Param id path string true "区域主控ID"
|
||||||
|
// @Success 200 {object} controller.Response{data=AreaControllerResponse}
|
||||||
|
// @Router /api/v1/area-controllers/{id} [get]
|
||||||
|
func (c *Controller) GetAreaController(ctx *gin.Context) {
|
||||||
|
const actionType = "获取区域主控"
|
||||||
|
acID := ctx.Param("id")
|
||||||
|
|
||||||
|
idUint, err := strconv.ParseUint(acID, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
c.logger.Errorf("%s: 区域主控ID格式错误: %v, ID: %s", actionType, err, acID)
|
||||||
|
controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的区域主控ID格式", actionType, "ID格式错误", acID)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ac, err := c.areaControllerRepo.FindByID(uint(idUint))
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
c.logger.Warnf("%s: 区域主控不存在, ID: %s", actionType, acID)
|
||||||
|
controller.SendErrorWithAudit(ctx, controller.CodeNotFound, "区域主控未找到", actionType, "区域主控不存在", acID)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.logger.Errorf("%s: 数据库查询失败: %v, ID: %s", actionType, err, acID)
|
||||||
|
controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取区域主控信息失败: "+err.Error(), actionType, "数据库查询失败", acID)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := newAreaControllerResponse(ac)
|
||||||
|
if err != nil {
|
||||||
|
c.logger.Errorf("%s: 序列化响应失败: %v, AreaController: %+v", actionType, err, ac)
|
||||||
|
controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取区域主控信息失败: 内部数据格式错误", actionType, "响应序列化失败", ac)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.logger.Infof("%s: 获取区域主控信息成功, ID: %d", actionType, ac.ID)
|
||||||
|
controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "获取区域主控信息成功", resp, actionType, "获取区域主控信息成功", resp)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListAreaControllers godoc
|
||||||
|
// @Summary 获取所有区域主控列表
|
||||||
|
// @Description 获取系统中所有区域主控的列表
|
||||||
|
// @Tags 区域主控管理
|
||||||
|
// @Produce json
|
||||||
|
// @Success 200 {object} controller.Response{data=[]AreaControllerResponse}
|
||||||
|
// @Router /api/v1/area-controllers [get]
|
||||||
|
func (c *Controller) ListAreaControllers(ctx *gin.Context) {
|
||||||
|
const actionType = "获取区域主控列表"
|
||||||
|
acs, err := c.areaControllerRepo.ListAll()
|
||||||
|
if err != nil {
|
||||||
|
c.logger.Errorf("%s: 数据库查询失败: %v", actionType, err)
|
||||||
|
controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取区域主控列表失败: "+err.Error(), actionType, "数据库查询失败", nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := newListAreaControllerResponse(acs)
|
||||||
|
if err != nil {
|
||||||
|
c.logger.Errorf("%s: 序列化响应失败: %v, AreaControllers: %+v", actionType, err, acs)
|
||||||
|
controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "获取区域主控列表失败: 内部数据格式错误", actionType, "响应序列化失败", acs)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.logger.Infof("%s: 获取区域主控列表成功, 数量: %d", actionType, len(acs))
|
||||||
|
controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "获取区域主控列表成功", resp, actionType, "获取区域主控列表成功", resp)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UpdateAreaController godoc
|
||||||
|
// @Summary 更新区域主控信息
|
||||||
|
// @Description 根据ID更新一个已存在的区域主控信息
|
||||||
|
// @Tags 区域主控管理
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Param id path string true "区域主控ID"
|
||||||
|
// @Param areaController body UpdateAreaControllerRequest true "要更新的区域主控信息"
|
||||||
|
// @Success 200 {object} controller.Response{data=AreaControllerResponse}
|
||||||
|
// @Router /api/v1/area-controllers/{id} [put]
|
||||||
|
func (c *Controller) UpdateAreaController(ctx *gin.Context) {
|
||||||
|
const actionType = "更新区域主控"
|
||||||
|
acID := ctx.Param("id")
|
||||||
|
|
||||||
|
idUint, err := strconv.ParseUint(acID, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
c.logger.Errorf("%s: 区域主控ID格式错误: %v, ID: %s", actionType, err, acID)
|
||||||
|
controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的区域主控ID格式", actionType, "ID格式错误", acID)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
existingAC, err := c.areaControllerRepo.FindByID(uint(idUint))
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
c.logger.Warnf("%s: 区域主控不存在, ID: %s", actionType, acID)
|
||||||
|
controller.SendErrorWithAudit(ctx, controller.CodeNotFound, "区域主控未找到", actionType, "区域主控不存在", acID)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.logger.Errorf("%s: 数据库查询失败: %v, ID: %s", actionType, err, acID)
|
||||||
|
controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "更新区域主控失败: "+err.Error(), actionType, "数据库查询失败", acID)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var req UpdateAreaControllerRequest
|
||||||
|
if err := ctx.ShouldBindJSON(&req); err != nil {
|
||||||
|
c.logger.Errorf("%s: 参数绑定失败: %v", actionType, err)
|
||||||
|
controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的请求体: "+err.Error(), actionType, "请求体绑定失败", req)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
propertiesJSON, err := json.Marshal(req.Properties)
|
||||||
|
if err != nil {
|
||||||
|
c.logger.Errorf("%s: 序列化属性失败: %v", actionType, err)
|
||||||
|
controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "属性字段格式错误", actionType, "属性序列化失败", req.Properties)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
existingAC.Name = req.Name
|
||||||
|
existingAC.NetworkID = req.NetworkID
|
||||||
|
existingAC.Location = req.Location
|
||||||
|
existingAC.Properties = propertiesJSON
|
||||||
|
|
||||||
|
if err := existingAC.SelfCheck(); err != nil {
|
||||||
|
c.logger.Errorf("%s: 区域主控自检失败: %v", actionType, err)
|
||||||
|
controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "区域主控参数不符合要求: "+err.Error(), actionType, "区域主控自检失败", existingAC)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := c.areaControllerRepo.Update(existingAC); err != nil {
|
||||||
|
c.logger.Errorf("%s: 数据库更新失败: %v, AreaController: %+v", actionType, err, existingAC)
|
||||||
|
controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "更新区域主控失败: "+err.Error(), actionType, "数据库更新失败", existingAC)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := newAreaControllerResponse(existingAC)
|
||||||
|
if err != nil {
|
||||||
|
c.logger.Errorf("%s: 序列化响应失败: %v, AreaController: %+v", actionType, err, existingAC)
|
||||||
|
controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "区域主控更新成功,但响应生成失败", actionType, "响应序列化失败", existingAC)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.logger.Infof("%s: 区域主控更新成功, ID: %d", actionType, existingAC.ID)
|
||||||
|
controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "区域主控更新成功", resp, actionType, "区域主控更新成功", resp)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteAreaController godoc
|
||||||
|
// @Summary 删除区域主控
|
||||||
|
// @Description 根据ID删除一个区域主控(软删除)
|
||||||
|
// @Tags 区域主控管理
|
||||||
|
// @Produce json
|
||||||
|
// @Param id path string true "区域主控ID"
|
||||||
|
// @Success 200 {object} controller.Response
|
||||||
|
// @Router /api/v1/area-controllers/{id} [delete]
|
||||||
|
func (c *Controller) DeleteAreaController(ctx *gin.Context) {
|
||||||
|
const actionType = "删除区域主控"
|
||||||
|
acID := ctx.Param("id")
|
||||||
|
|
||||||
|
idUint, err := strconv.ParseUint(acID, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
c.logger.Errorf("%s: 区域主控ID格式错误: %v, ID: %s", actionType, err, acID)
|
||||||
|
controller.SendErrorWithAudit(ctx, controller.CodeBadRequest, "无效的区域主控ID格式", actionType, "ID格式错误", acID)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = c.areaControllerRepo.FindByID(uint(idUint))
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
c.logger.Warnf("%s: 区域主控不存在, ID: %s", actionType, acID)
|
||||||
|
controller.SendErrorWithAudit(ctx, controller.CodeNotFound, "区域主控未找到", actionType, "区域主控不存在", acID)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.logger.Errorf("%s: 查找区域主控失败: %v, ID: %s", actionType, err, acID)
|
||||||
|
controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "删除区域主控失败: 查找时发生内部错误", actionType, "数据库查询失败", acID)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := c.areaControllerRepo.Delete(uint(idUint)); err != nil {
|
||||||
|
c.logger.Errorf("%s: 数据库删除失败: %v, ID: %d", actionType, err, idUint)
|
||||||
|
controller.SendErrorWithAudit(ctx, controller.CodeInternalError, "删除区域主控失败: "+err.Error(), actionType, "数据库删除失败", acID)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.logger.Infof("%s: 区域主控删除成功, ID: %d", actionType, idUint)
|
||||||
|
controller.SendSuccessWithAudit(ctx, controller.CodeSuccess, "区域主控删除成功", nil, actionType, "区域主控删除成功", acID)
|
||||||
|
}
|
||||||
|
|||||||
@@ -129,6 +129,7 @@ func NewApplication(configPath string) (*Application, error) {
|
|||||||
logger,
|
logger,
|
||||||
userRepo,
|
userRepo,
|
||||||
deviceRepo,
|
deviceRepo,
|
||||||
|
areaControllerRepo,
|
||||||
planRepo,
|
planRepo,
|
||||||
userActionLogRepo,
|
userActionLogRepo,
|
||||||
tokenService,
|
tokenService,
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package repository
|
package repository
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"git.huangwc.com/pig/pig-farm-controller/internal/infra/models"
|
"git.huangwc.com/pig/pig-farm-controller/internal/infra/models"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
@@ -8,7 +10,11 @@ import (
|
|||||||
// AreaControllerRepository 定义了对 AreaController 模型的数据库操作接口
|
// AreaControllerRepository 定义了对 AreaController 模型的数据库操作接口
|
||||||
type AreaControllerRepository interface {
|
type AreaControllerRepository interface {
|
||||||
FindByID(id uint) (*models.AreaController, error)
|
FindByID(id uint) (*models.AreaController, error)
|
||||||
FindByNetworkID(networkID string) (*models.AreaController, error) // New method
|
FindByNetworkID(networkID string) (*models.AreaController, error)
|
||||||
|
Create(ac *models.AreaController) error
|
||||||
|
ListAll() ([]*models.AreaController, error)
|
||||||
|
Update(ac *models.AreaController) error
|
||||||
|
Delete(id uint) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// gormAreaControllerRepository 是 AreaControllerRepository 的 GORM 实现。
|
// gormAreaControllerRepository 是 AreaControllerRepository 的 GORM 实现。
|
||||||
@@ -21,6 +27,48 @@ func NewGormAreaControllerRepository(db *gorm.DB) AreaControllerRepository {
|
|||||||
return &gormAreaControllerRepository{db: db}
|
return &gormAreaControllerRepository{db: db}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create 创建一个新的 AreaController 记录。
|
||||||
|
func (r *gormAreaControllerRepository) Create(ac *models.AreaController) error {
|
||||||
|
return r.db.Create(ac).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListAll 返回所有 AreaController 的列表。
|
||||||
|
func (r *gormAreaControllerRepository) ListAll() ([]*models.AreaController, error) {
|
||||||
|
var areaControllers []*models.AreaController
|
||||||
|
if err := r.db.Find(&areaControllers).Error; err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return areaControllers, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update 更新一个已存在的 AreaController 记录。
|
||||||
|
func (r *gormAreaControllerRepository) Update(ac *models.AreaController) error {
|
||||||
|
return r.db.Save(ac).Error
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete 删除一个 AreaController 记录。
|
||||||
|
// 在删除前会检查是否有设备关联到该主控,如果有,则不允许删除。
|
||||||
|
func (r *gormAreaControllerRepository) Delete(id uint) error {
|
||||||
|
return r.db.Transaction(func(tx *gorm.DB) error {
|
||||||
|
// 检查是否有设备关联到这个区域主控
|
||||||
|
var count int64
|
||||||
|
if err := tx.Model(&models.Device{}).Where("area_controller_id = ?", id).Count(&count).Error; err != nil {
|
||||||
|
return fmt.Errorf("检查关联设备失败: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if count > 0 {
|
||||||
|
return fmt.Errorf("无法删除区域主控,因为仍有 %d 个设备关联到它", count)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果没有关联设备,则执行删除操作
|
||||||
|
if err := tx.Delete(&models.AreaController{}, id).Error; err != nil {
|
||||||
|
return fmt.Errorf("删除区域主控失败: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// FindByID 通过 ID 查找一个 AreaController。
|
// FindByID 通过 ID 查找一个 AreaController。
|
||||||
func (r *gormAreaControllerRepository) FindByID(id uint) (*models.AreaController, error) {
|
func (r *gormAreaControllerRepository) FindByID(id uint) (*models.AreaController, error) {
|
||||||
var areaController models.AreaController
|
var areaController models.AreaController
|
||||||
|
|||||||
Reference in New Issue
Block a user