Browse Source

开关控制

xu 1 day ago
parent
commit
d05dd079f2

+ 17 - 0
server/api/v1/admin/device.go

@@ -59,6 +59,23 @@ func (da *DeviceApi) GenerateDeviceFile(c *gin.Context) {
 	response.OkWithData(data, c)
 }
 
+func (da *DeviceApi) DeviceSwitch(c *gin.Context) {
+	var info request.SwitchTunnel
+	err := c.ShouldBindJSON(&info)
+	if err != nil {
+		logger.Get().Error("DeviceSwitch ---- " + err.Error())
+		response.FailWithMessage("参数解析失败", c)
+		return
+	}
+	err = deviceService.DeviceSwitch(info)
+	if err != nil {
+		logger.Get().Error("DeviceSwitch ---- " + err.Error())
+		response.FailWithMessage("设备状态切换失败", c)
+		return
+	}
+	response.Ok(c)
+}
+
 func (da *DeviceApi) CreateDevice(c *gin.Context) {
 	var device dao.Device
 	err := c.ShouldBindJSON(&device)

+ 17 - 0
server/api/v1/admin/tunnel.go

@@ -85,6 +85,23 @@ func (ta *TunnelApi) UpdateTunnel(c *gin.Context) {
 	response.OkWithMessage("更新隧道成功", c)
 }
 
+func (ta *TunnelApi) UpdateTunnelLamp(c *gin.Context) {
+	var info request.TunnelLamp
+	err := c.ShouldBindJSON(&info)
+	if err != nil {
+		logger.Get().Error("UpdateTunnelLamp ---- " + err.Error())
+		response.FailWithMessage("参数解析失败", c)
+		return
+	}
+	err = tunnelService.UpdateTunnelLamp(info)
+	if err != nil {
+		logger.Get().Error("UpdateTunnelLamp ---- " + err.Error())
+		response.FailWithMessage("更新隧道灯光状态失败", c)
+		return
+	}
+	response.OkWithMessage("更新隧道灯光状态成功", c)
+}
+
 func (ta *TunnelApi) UpdateTactics(c *gin.Context) {
 	var tactics request.EditTactics
 	if err := c.ShouldBindJSON(&tactics); err != nil {

+ 17 - 0
server/api/v1/system/sys_user.go

@@ -2,6 +2,7 @@ package system
 
 import (
 	"server/dao"
+	"server/utils/logger"
 	"strconv"
 	"time"
 
@@ -243,6 +244,22 @@ func (b *BaseApi) GetUserList(c *gin.Context) {
 	}, "获取成功", c)
 }
 
+func (b *BaseApi) CreateUserTunnels(c *gin.Context) {
+	var info request.UserTunnels
+	err := c.ShouldBindJSON(&info)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = userService.CreateUserTunnels(info)
+	if err != nil {
+		logger.Get().Errorf("分配隧道失败! %v", err)
+		response.FailWithMessage("分配隧道失败", c)
+		return
+	}
+	response.OkWithMessage("分配隧道成功", c)
+}
+
 // SetUserAuthority
 // @Tags      SysUser
 // @Summary   更改用户权限

+ 56 - 16
server/dao/device.go

@@ -1,20 +1,24 @@
 package dao
 
-import "server/global"
+import (
+	"gorm.io/gorm"
+	"server/global"
+)
 
 type Device struct {
 	global.GVA_MODEL
-	Sn          string      `json:"sn" gorm:"comment:设备sn"`
-	Name        string      `json:"name" gorm:"comment:名称"`
-	Address     string      `json:"address" gorm:"comment:设备地址"`
-	TaskTime    uint        `json:"taskTime" gorm:"comment:采集时间"`
-	WaitTime    uint        `json:"waitTime" gorm:"comment:延迟时间"`
-	RadarId     int8        `json:"radarId" gorm:"comment:雷达id"`
-	SerialId    int8        `json:"serialId" gorm:"comment:串口id"`
-	Genre       int         `json:"genre" gorm:"index;comment:类型id"`
-	DeviceGenre DeviceGenre `json:"deviceGenre" gorm:"foreignKey:Genre;"`
-	TunnelId    int         `json:"tunnelId" gorm:"column:tunnel_id"`
-	Tunnel      Tunnel      `json:"tunnel" gorm:"foreignKey:TunnelId"`
+	Sn           string        `json:"sn" gorm:"comment:设备sn"`
+	Name         string        `json:"name" gorm:"comment:名称"`
+	Address      string        `json:"address" gorm:"comment:设备地址"`
+	TaskTime     uint          `json:"taskTime" gorm:"comment:采集时间"`
+	WaitTime     uint          `json:"waitTime" gorm:"comment:延迟时间"`
+	RadarId      int8          `json:"radarId" gorm:"comment:雷达id"`
+	SerialId     int8          `json:"serialId" gorm:"comment:串口id"`
+	Genre        int           `json:"genre" gorm:"index;comment:类型id"`
+	DeviceGenre  DeviceGenre   `json:"deviceGenre" gorm:"foreignKey:Genre;"`
+	TunnelId     int           `json:"tunnelId" gorm:"column:tunnel_id"`
+	Tunnel       Tunnel        `json:"tunnel" gorm:"foreignKey:TunnelId"`
+	DeviceRelays []DeviceRelay `json:"deviceRelays" gorm:"foreignKey:DeviceId"`
 }
 
 func (Device) TableName() string {
@@ -22,7 +26,7 @@ func (Device) TableName() string {
 }
 
 func QueryAllDevices() (devices []Device, err error) {
-	err = global.GVA_DB.Model(Device{}).Preload("DeviceGenre").Preload("Tunnel").Find(&devices).Error
+	err = global.GVA_DB.Model(Device{}).Preload("DeviceGenre").Preload("DeviceRelays").Preload("Tunnel").Find(&devices).Error
 	return
 }
 
@@ -44,17 +48,53 @@ func QueryDeviceList(sn, name string, genre, limit, offset int) (devices []Devic
 	if err != nil {
 		return
 	}
-	err = db.Limit(limit).Offset(offset).Preload("DeviceGenre").Preload("Tunnel").Find(&devices).Error
+	err = db.Limit(limit).Offset(offset).Preload("DeviceGenre").Preload("DeviceRelays").Preload("Tunnel").Find(&devices).Error
 	return
 }
 
 func QueryDeviceByTunnelId(id int) (devices []Device, err error) {
-	err = global.GVA_DB.Where("tunnel_id =?", id).Preload("DeviceGenre").Preload("Tunnel").Find(&devices).Error
+	err = global.GVA_DB.Where("tunnel_id =?", id).Preload("DeviceGenre").Preload("DeviceRelays").Preload("Tunnel").Find(&devices).Error
+	return
+}
+
+func QueryGenreByTunnel(id int) (devices []Device, err error) {
+	err = global.GVA_DB.Model(&Device{}).
+		Select("device.*").
+		Joins("JOIN device_genre ON device.genre = device_genre.id").
+		Where("device.tunnel_id = ? AND device_genre.type = ?", id, "开关设备").
+		Find(&devices).Error
+	return
+}
+
+func QueryDeviceByTunnelSnAndRadarId(sn string, id int) (device Device, err error) {
+	err = global.GVA_DB.Model(&Device{}).
+		Select("device.*").
+		Joins("JOIN tunnel ON device.tunnel_id = tunnel.id").
+		Where("device.radar_id = ? AND tunnel.tunnel_sn = ?", id, sn).
+		First(&device).Error
 	return
 }
 
 func (d Device) CreateDevice() error {
-	return global.GVA_DB.Create(&d).Error
+	return global.GVA_DB.Transaction(func(tx *gorm.DB) error {
+		err := tx.Create(&d).Error
+		if err != nil {
+			return err
+		}
+		if d.Genre != 6 {
+			return nil
+		}
+		var deviceRelays []DeviceRelay
+		for i := 1; i <= 4; i++ {
+			relay := DeviceRelay{
+				RelayID:  i,
+				DeviceId: int(d.ID),
+				State:    false,
+			}
+			deviceRelays = append(deviceRelays, relay)
+		}
+		return tx.Create(&deviceRelays).Error
+	})
 }
 
 func (d Device) UpdateDevice() error {

+ 5 - 0
server/dao/device_genre.go

@@ -17,6 +17,11 @@ func QueryAllDeviceGenres() (genres []DeviceGenre, err error) {
 	return
 }
 
+func QueryDeviceGenreByID(id int) (genre DeviceGenre, err error) {
+	err = global.GVA_DB.Where("id = ?", id).First(&genre).Error
+	return
+}
+
 func (d DeviceGenre) CreateDeviceGenre() error {
 	return global.GVA_DB.Create(&d).Error
 }

+ 18 - 0
server/dao/device_relay.go

@@ -0,0 +1,18 @@
+package dao
+
+import "server/global"
+
+type DeviceRelay struct {
+	ID       int  `json:"id"`
+	RelayID  int  `json:"relayId" gorm:"comment:回路id"`
+	DeviceId int  `json:"deviceId" gorm:"comment:设备id"`
+	State    bool `json:"state" gorm:"comment:设备状态"`
+}
+
+func (DeviceRelay) TableName() string {
+	return "device_relay"
+}
+
+func UpdateRelayState(deviceId, relayId int, state bool) error {
+	return global.GVA_DB.Model(&DeviceRelay{}).Debug().Where("device_id = ? AND relay_id = ?", deviceId, relayId).Update("state", state).Error
+}

+ 18 - 7
server/dao/sys_user.go

@@ -19,6 +19,7 @@ type SysUser struct {
 	ActiveColor string       `json:"activeColor" gorm:"default:#1890ff;comment:活跃颜色"`                                      // 活跃颜色
 	AuthorityId uint         `json:"authorityId" gorm:"default:888;comment:用户角色ID"`                                        // 用户角色ID
 	Authority   SysAuthority `json:"authority" gorm:"foreignKey:AuthorityId;references:AuthorityId;comment:用户角色"`
+	TunnelIds   []int        `json:"tunnelIds" gorm:"-"`
 	Tunnels     []Tunnel     `json:"tunnels" gorm:"many2many:user_tunnel"`
 	Phone       string       `json:"phone"  gorm:"comment:用户手机号"`                     // 用户手机号
 	Email       string       `json:"email"  gorm:"comment:用户邮箱"`                      // 用户邮箱
@@ -29,11 +30,6 @@ func (SysUser) TableName() string {
 	return "sys_users"
 }
 
-// TODO:查询
-// TODO:新增
-// TODO:修改
-// TODO:删除
-
 // TODO: 用户查询
 
 // QueryUserByUserName  按用户名查询用户
@@ -52,7 +48,7 @@ func QueryUserByUserId(id uint) (SysUser, error) {
 
 // QueryUserAndAuthorityByUserName 按用户名查询用户和角色
 func QueryUserAndAuthorityByUserName(userName string) (user SysUser, err error) {
-	err = global.GVA_DB.Where("username = ?", userName).Preload("Authority").First(&user).Error
+	err = global.GVA_DB.Where("username = ?", userName).Preload("Authority").Preload("Tunnels").First(&user).Error
 	return
 }
 
@@ -63,10 +59,25 @@ func QueryUserInfoList(limit, offset int) (userList []SysUser, total int64, err
 	if err != nil {
 		return
 	}
-	err = db.Limit(limit).Offset(offset).Preload("Authority").Find(&userList).Error
+	err = db.Limit(limit).Offset(offset).Preload("Authority").Preload("Tunnels").Find(&userList).Error
 	return
 }
 
+func CreateUserTunnels(user SysUser, ids []int) error {
+	return global.GVA_DB.Transaction(func(tx *gorm.DB) error {
+		var tunnels []Tunnel
+		err := tx.Model(&Tunnel{}).Where("id in (?)", ids).Find(&tunnels).Error
+		if err != nil {
+			return err
+		}
+		err = tx.Model(&user).Debug().Association("Tunnels").Replace(tunnels)
+		if err != nil {
+			return err
+		}
+		return nil
+	})
+}
+
 // QueryUserAuthority 查询用户角色
 func QueryUserAuthority(id, authorityId uint) (authority SysAuthority, err error) {
 	err = global.GVA_DB.Where("sys_user_id = ? AND sys_authority_authority_id = ?", id, authorityId).First(&authority).Error

+ 14 - 2
server/dao/tunnel.go

@@ -13,6 +13,9 @@ type Tunnel struct {
 	RegionId    int           `json:"regionId" gorm:"column:region_id"`
 	Region      Region        `json:"region" gorm:"foreignKey:RegionId"` // 关系
 	TimeId      int           `json:"timeId" gorm:"comment:定时id"`
+	SwitchType  string        `json:"switchType" gorm:"comment:开关类型"`
+	LampValue1  int           `json:"lampValue1" gorm:"comment:1路单灯值"`
+	LampValue2  int           `json:"lampValue2" gorm:"comment:2路单灯值"`
 	TunnelTime  TunnelTime    `json:"tunnelTime" gorm:"foreignKey:TimeId"`
 	Users       []SysUser     `json:"users" gorm:"many2many:user_tunnel"`
 	Devices     []Device      `json:"devices" gorm:"foreignKey:TunnelId"`
@@ -25,7 +28,7 @@ func (Tunnel) TableName() string {
 }
 
 func QueryAllTunnels() (tunnels []Tunnel, err error) {
-	err = global.GVA_DB.Find(&tunnels).Preload("Users").Preload("TunnelTime").Preload("Devices").Preload("Region").Preload("EnvData").Preload("OpticalData").Error
+	err = global.GVA_DB.Find(&tunnels).Preload("Users").Preload("TunnelTime").Preload("Devices").Preload("Devices.DeviceRelays").Preload("Devices.Tunnel").Preload("Region").Preload("EnvData").Preload("OpticalData").Error
 	return tunnels, err
 }
 
@@ -45,7 +48,7 @@ func QueryTunnelList(name string, regionId, userId, limit, offset int) (tunnels
 	if err != nil {
 		return
 	}
-	err = db.Limit(limit).Offset(offset).Preload("Users").Preload("TunnelTime").Preload("Devices").Preload("Region").Preload("EnvData").Preload("OpticalData").Find(&tunnels).Error
+	err = db.Limit(limit).Offset(offset).Preload("Users").Preload("TunnelTime").Preload("Devices").Preload("Devices.DeviceRelays").Preload("Devices.Tunnel").Preload("Region").Preload("EnvData").Preload("OpticalData").Find(&tunnels).Error
 	return
 }
 
@@ -54,6 +57,11 @@ func QueryNoRegionTunnels() (tunnels []Tunnel, err error) {
 	return
 }
 
+func QueryTunnelById(id int) (tunnel Tunnel, err error) {
+	err = global.GVA_DB.Where("id =?", id).Preload("Users").Preload("TunnelTime").Preload("Devices").Preload("Devices.DeviceRelays").Preload("Devices.Tunnel").Preload("Region").Preload("EnvData").Preload("OpticalData").First(&tunnel).Error
+	return
+}
+
 func QueryTunnelByRegionId(id int) (tunnels []Tunnel, err error) {
 	err = global.GVA_DB.Where("region_id =?", id).Find(&tunnels).Error
 	return
@@ -83,6 +91,10 @@ func (t Tunnel) UpdateTunnel() error {
 	return global.GVA_DB.Where("id = ?", t.ID).Updates(&t).Error
 }
 
+func UpdateTunnelLamp(id, lamp1, lamp2 int) error {
+	return global.GVA_DB.Model(&Tunnel{}).Where("id =?", id).Update("lamp_value1", lamp1).Update("lamp_value2", lamp2).Error
+}
+
 func UpdateTactics(sn string, tactics int) error {
 	return global.GVA_DB.Model(&Tunnel{}).Where("tunnel_sn =?", sn).Update("tactics", tactics).Error
 }

+ 1 - 0
server/initialize/gorm.go

@@ -51,6 +51,7 @@ func RegisterTables() {
 		dao.TunnelTime{},
 		dao.Device{},
 		dao.DeviceGenre{},
+		dao.DeviceRelay{},
 		dao.EnvData{},
 		dao.OpticalData{},
 	)

+ 14 - 0
server/model/common/request/common.go

@@ -56,4 +56,18 @@ type UserTunnels struct {
 	TunnelIds []int       `json:"tunnelIds" form:"tunnelIds"`
 }
 
+type SwitchTunnel struct {
+	TunnelSn string `json:"tunnelSn" form:"tunnelSn"`
+	RadarId  int    `json:"radarId"`
+	RelayId  int    `json:"relayId"`
+	State    bool   `json:"state"`
+}
+
+type TunnelLamp struct {
+	Id         int    `json:"id" form:"id"`
+	TunnelSn   string `json:"tunnelSn" form:"tunnelSn"`
+	LampValue1 int    `json:"lampValue1"`
+	LampValue2 int    `json:"lampValue2"`
+}
+
 type Empty struct{}

+ 1 - 0
server/router/admin/device.go

@@ -15,6 +15,7 @@ func (dr *DeviceRouter) InitDeviceRouter(Router *gin.RouterGroup) {
 	{
 		deviceRouter.POST("queryDeviceList", deviceRouterApi.QueryDeviceList)
 		deviceRouter.POST("createDevice", deviceRouterApi.CreateDevice)
+		deviceRouter.POST("deviceSwitch", deviceRouterApi.DeviceSwitch)
 		deviceRouter.PUT("updateDevice", deviceRouterApi.UpdateDevice)
 		deviceRouter.DELETE("deleteDevice", deviceRouterApi.DeleteDevice)
 	}

+ 1 - 0
server/router/admin/tunnel.go

@@ -16,6 +16,7 @@ func (tr *TunnelRouter) InitTunnelRouter(Router *gin.RouterGroup) {
 		tunnelRouter.POST("queryTunnelList", tunnelRouterApi.QueryTunnelList)
 		tunnelRouter.POST("createTunnel", tunnelRouterApi.CreateTunnel)
 		tunnelRouter.PUT("updateTunnel", tunnelRouterApi.UpdateTunnel)
+		tunnelRouter.PUT("updateTunnelLamp", tunnelRouterApi.UpdateTunnelLamp)
 		tunnelRouter.PUT("updateTactics", tunnelRouterApi.UpdateTactics)
 		tunnelRouter.PUT("updateTunnelsRegion", tunnelRouterApi.UpdateTunnelsRegion)
 		tunnelRouter.PUT("updateTunnelTime", tunnelRouterApi.UpdateTunnelTime)

+ 1 - 0
server/router/system/sys_user.go

@@ -19,6 +19,7 @@ func (s *UserRouter) InitUserRouter(Router *gin.RouterGroup) {
 		userRouter.DELETE("deleteUser", baseApi.DeleteUser)               // 删除用户
 		userRouter.PUT("setUserInfo", baseApi.SetUserInfo)                // 设置用户信息
 		userRouter.PUT("setSelfInfo", baseApi.SetSelfInfo)                // 设置自身信息
+		userRouter.POST("createUserTunnels", baseApi.CreateUserTunnels)   // 分配隧道
 		userRouter.POST("setUserAuthorities", baseApi.SetUserAuthorities) // 设置用户权限组
 		userRouter.POST("resetPassword", baseApi.ResetPassword)           // 设置用户权限组
 	}

+ 39 - 0
server/service/admin/device.go

@@ -1,9 +1,12 @@
 package admin
 
 import (
+	"fmt"
 	"server/dao"
 	"server/model/common/request"
 	"server/model/common/response"
+	"server/utils/protocol"
+	"strconv"
 )
 
 type DeviceService struct{}
@@ -52,7 +55,43 @@ func (ds *DeviceService) GenerateDeviceFile(id int) (data response.DeviceFileDat
 	return data, nil
 }
 
+func (ds *DeviceService) DeviceSwitch(info request.SwitchTunnel) error {
+	device, err := dao.QueryDeviceByTunnelSnAndRadarId(info.TunnelSn, info.RadarId)
+	if err != nil {
+		return err
+	}
+	err = dao.UpdateRelayState(int(device.ID), info.RelayId, info.State)
+	if err != nil {
+		return err
+	}
+	var i int
+	if info.State {
+		i = 1
+	} else {
+		i = 0
+	}
+	data := strconv.Itoa(info.RadarId) + strconv.Itoa(info.RelayId) + strconv.Itoa(i)
+	err = MqttService.Publish(MqttService.GetTopic(info.TunnelSn, protocol.TopicSwitchControl), []byte(data))
+	if err != nil {
+		return fmt.Errorf("error updating: %v", err)
+	}
+	return nil
+}
+
 func (ds *DeviceService) CreateDevice(device dao.Device) error {
+	tunnel, err := dao.QueryTunnelById(device.TunnelId)
+	if err != nil {
+		return err
+	}
+	genre, err := dao.QueryDeviceGenreByID(device.Genre)
+	if err != nil {
+		return err
+	}
+
+	if genre.Name == tunnel.SwitchType && genre.Type == "开关设备" {
+		return fmt.Errorf("开关设备需安装隧道需求添加")
+	}
+
 	return device.CreateDevice()
 }
 

+ 14 - 1
server/service/admin/tunnel.go

@@ -34,8 +34,21 @@ func (ts *TunnelService) UpdateTunnel(tunnel dao.Tunnel) error {
 	return tunnel.UpdateTunnel()
 }
 
+func (ts *TunnelService) UpdateTunnelLamp(info request.TunnelLamp) error {
+	data1 := strconv.Itoa(1) + strconv.Itoa(info.LampValue1)
+	data2 := strconv.Itoa(2) + strconv.Itoa(info.LampValue2)
+	err := MqttService.Publish(MqttService.GetTopic(info.TunnelSn, protocol.TopicLampControl), []byte(data1))
+	if err != nil {
+		return fmt.Errorf("error updating: %v", err)
+	}
+	err = MqttService.Publish(MqttService.GetTopic(info.TunnelSn, protocol.TopicLampControl), []byte(data2))
+	if err != nil {
+		return fmt.Errorf("error updating: %v", err)
+	}
+	return dao.UpdateTunnelLamp(info.Id, info.LampValue1, info.LampValue2)
+}
+
 func (ts *TunnelService) UpdateTactics(sn string, tactics int) error {
-	fmt.Println(sn, tactics)
 	err := MqttService.Publish(MqttService.GetTopic(sn, protocol.TopicTunnelTactics), strconv.Itoa(tactics))
 	if err != nil {
 		return fmt.Errorf("error updating: %v", err)

+ 11 - 0
server/service/system/sys_user.go

@@ -88,9 +88,20 @@ func (userService *UserService) GetUserInfoList(info request.PageInfo) (list int
 
 	userList, total, err := dao.QueryUserInfoList(limit, offset)
 
+	for i, user := range userList {
+		for _, tunnel := range user.Tunnels {
+			userList[i].TunnelIds = append(userList[i].TunnelIds, int(tunnel.ID))
+		}
+	}
+
 	return userList, total, err
 }
 
+func (UserService *UserService) CreateUserTunnels(info request.UserTunnels) error {
+	fmt.Println(info)
+	return dao.CreateUserTunnels(info.User, info.TunnelIds)
+}
+
 //@author: [piexlmax](https://github.com/piexlmax)
 //@function: SetUserAuthority
 //@description: 设置一个用户的权限

+ 1 - 0
server/utils/protocol/protocol.go

@@ -4,6 +4,7 @@ const (
 	TopicGatherDataEnv = "gatherDataEnv"
 	TopicGatherDataOpt = "gatherDataOpt"
 	TopicLampControl   = "lampControl"
+	TopicSwitchControl = "switchControl"
 	TopicTunnelTactics = "tunnelTactics"
 	TopicTunnelTiming  = "tunnelTiming"
 )

+ 112 - 19
web/src/view/admin/tunnel/tunnel.vue

@@ -71,6 +71,11 @@
           label="地区"
           align="center"
         />
+        <el-table-column
+          prop="switchType"
+          label="开关类型"
+          align="center"
+        />
         <el-table-column
           label="策略"
           align="center"
@@ -172,6 +177,15 @@
             />
           </el-select>
         </el-form-item>
+        <el-form-item
+          v-if="userInfo.authorityId === 888"
+          label="开关类型"
+        >
+          <el-input
+            v-model="tunnelData.switchType"
+            style="width: 200px;"
+          />
+        </el-form-item>
       </el-form>
       <template #footer>
         <div class="dialog-footer">
@@ -222,6 +236,15 @@
             />
           </el-select>
         </el-form-item>
+        <el-form-item
+          v-if="userInfo.authorityId === 888"
+          label="开关类型"
+        >
+          <el-input
+            v-model="tunnelData.switchType"
+            style="width: 200px;"
+          />
+        </el-form-item>
       </el-form>
       <template #footer>
         <div class="dialog-footer">
@@ -288,13 +311,50 @@
     >
       <el-collapse
         v-model="activeNames"
-        @change="handleChange"
       >
         <el-collapse-item
           title="开关"
           name="1"
         >
-          1
+          <div v-if="tunnelTimeData.switchType === '四路控制器'">
+            <div
+              v-for="(item, index) in tunnelTimeData.devices"
+              key="index"
+              style="margin: 10px 0"
+            >
+              <span style="margin: 0 20px 0 0;font-weight: 600;font-size: 16px">道路 {{ item.radarId }}</span>
+              <el-switch
+                v-for="(v, k) in item.deviceRelays"
+                key="k"
+                v-model="v.state"
+                class="ml-2"
+                style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949"
+                @click="switchButton(item, v)"
+              />
+            </div>
+          </div>
+          <div v-if="tunnelTimeData.switchType === '单灯控制器'">
+            <div style="margin: 0 0 0 20px">
+              <el-slider
+                v-model="tunnelTimeData.lampValue1"
+                :step="10"
+                style="width: 50%;"
+                show-stops
+              />
+            </div>
+            <div style="margin: 0 0 0 20px">
+              <el-slider
+                v-model="tunnelTimeData.lampValue2"
+                :step="10"
+                style="width: 50%;"
+                show-stops
+              />
+            </div>
+            <el-button
+              type="success"
+              @click="lampSet(tunnelTimeData)"
+            >设定</el-button>
+          </div>
         </el-collapse-item>
         <el-collapse-item
           title="定时"
@@ -329,16 +389,16 @@
             >
               存储数据
             </el-button>
-            <span style="margin-left: 30px">
-              <el-tag
-                v-if="tunnelTimeData.tunnelTime.isComplete"
-                type="success"
-              >完成</el-tag>
-              <el-tag
-                v-if="!tunnelTimeData.tunnelTime.isComplete"
-                type="warning"
-              >正在发送</el-tag>
-            </span>
+            <!--            <span style="margin-left: 30px">-->
+            <!--              &lt;!&ndash;              <el-tag&ndash;&gt;-->
+            <!--              &lt;!&ndash;                v-if="tunnelTimeData.tunnelTime.isComplete"&ndash;&gt;-->
+            <!--              &lt;!&ndash;                type="success"&ndash;&gt;-->
+            <!--              &lt;!&ndash;              >完成</el-tag>&ndash;&gt;-->
+            <!--              <el-tag-->
+            <!--                v-if="!tunnelTimeData.tunnelTime.isComplete"-->
+            <!--                type="warning"-->
+            <!--              >正在发送</el-tag>-->
+            <!--            </span>-->
           </div>
         </el-collapse-item>
       </el-collapse>
@@ -353,12 +413,12 @@ import {
   createTunnel,
   deleteTunnel,
   queryTunnelList, updateTactics,
-  updateTunnel,
+  updateTunnel, updateTunnelLamp,
   updateTunnelsRegion,
   updateTunnelTime
 } from '@/api/tunnel'
 import { ElMessage, ElMessageBox } from 'element-plus'
-import { generateDeviceFile } from '@/api/device'
+import { deviceSwitch, generateDeviceFile } from '@/api/device'
 import { useUserStore } from '@/pinia/modules/user'
 const userData = useUserStore()
 const userInfo = userData.userInfo
@@ -397,7 +457,6 @@ const getData = async() => {
     total.value = res.data.total
     searchData.value.pageInfo.page = res.data.page
     searchData.value.pageInfo.pageSize = res.data.pageSize
-    console.log(tunnel.value)
   })
 }
 
@@ -427,12 +486,16 @@ const tunnelData = ref({
   id: 0,
   name: '',
   regionId: undefined,
-  tunnelSn: ''
+  tunnelSn: '',
+  switchType: ''
 })
 
 const tunnelAdd = async() => {
   tunnelData.value.id = 0
   await createTunnel(tunnelData.value).then(res => {
+    if (res.code === 0) {
+      ElMessage.success('添加成功')
+    }
     tunnelAddDialog.value = false
     getData()
   })
@@ -444,6 +507,9 @@ const tunnelEditDialog = ref(false)
 
 const tunnelEdit = async() => {
   await updateTunnel(tunnelData.value).then(res => {
+    if (res.code === 0) {
+      ElMessage.success('修改成功')
+    }
     tunnelEditDialog.value = false
     getData()
   })
@@ -597,9 +663,6 @@ const tunnelControlPanel = (val) => {
 }
 
 const activeNames = ref(['1', '2'])
-const handleChange = (val) => {
-  console.log(val)
-}
 
 // 定时
 
@@ -618,6 +681,36 @@ const editTunnelTiming = async() => {
   })
 }
 
+const lampSet = async(val) => {
+  await updateTunnelLamp({
+    id: val.ID,
+    tunnelSn: val.tunnelSn,
+    lampValue1: val.lampValue1,
+    lampValue2: val.lampValue2
+  }).then(res => {
+    if (res.code === 0) {
+      ElMessage.success('已发送')
+    }
+    getData()
+  })
+}
+
+// 开关
+const switchButton = async(device, relay) => {
+  console.log(device, relay)
+  await deviceSwitch({
+    tunnelSn: device.tunnel.tunnelSn,
+    radarId: device.radarId,
+    relayId: relay.relayId,
+    state: relay.state
+  }).then(res => {
+    if (res.code === 0) {
+      ElMessage.success('已切换')
+    }
+    getData()
+  })
+}
+
 onMounted(() => {
   getData()
 })