Quellcode durchsuchen

网关、摄像头、屏初步

chengqian vor 1 Jahr
Ursprung
Commit
4ff14ab345
39 geänderte Dateien mit 2619 neuen und 19 gelöschten Zeilen
  1. 125 0
      server/api/v1/devices/dev_camera.go
  2. 110 0
      server/api/v1/devices/dev_gateway.go
  3. 137 0
      server/api/v1/devices/dev_screens.go
  4. 15 0
      server/api/v1/devices/enter.go
  5. 2 0
      server/api/v1/enter.go
  6. 2 2
      server/conf/camera.json
  7. 1 1
      server/config.yaml
  8. 96 0
      server/dao/devices/dev_camera.go
  9. 64 1
      server/dao/devices/dev_gateway.go
  10. 87 0
      server/dao/devices/dev_screens.go
  11. 34 0
      server/dao/devices/screens_parameter.go
  12. 5 0
      server/initialize/gorm.go
  13. 6 0
      server/initialize/router.go
  14. 2 1
      server/initialize/tasks.go
  15. 2 1
      server/model/common/request/common.go
  16. 17 0
      server/model/devices/dev_camera.go
  17. 29 0
      server/model/devices/dev_gateway.go
  18. 27 0
      server/model/devices/dev_screens.go
  19. 23 0
      server/router/devices/dev_camera.go
  20. 29 0
      server/router/devices/dev_gateway.go
  21. 28 0
      server/router/devices/dev_screens.go
  22. 7 0
      server/router/devices/enter.go
  23. 2 0
      server/router/enter.go
  24. 43 0
      server/service/devices/dev_camera.go
  25. 62 0
      server/service/devices/dev_gateway.go
  26. 59 0
      server/service/devices/dev_screens.go
  27. 7 0
      server/service/devices/enter.go
  28. 2 0
      server/service/enter.go
  29. 5 3
      server/utils/mqtt/mqtt_handle.go
  30. 40 0
      web/src/api/camera.js
  31. 3 3
      web/src/api/fileUploadAndDownload.js
  32. 35 0
      web/src/api/gateway.js
  33. 40 0
      web/src/api/screens.js
  34. 5 5
      web/src/components/selectFile/selectFile.vue
  35. 2 2
      web/src/components/selectImage/selectImage.vue
  36. 478 0
      web/src/view/devicesAdmin/camera/camera.vue
  37. 472 0
      web/src/view/devicesAdmin/gateway/gateway.vue
  38. 23 0
      web/src/view/devicesAdmin/index.vue
  39. 493 0
      web/src/view/devicesAdmin/screens/screens.vue

+ 125 - 0
server/api/v1/devices/dev_camera.go

@@ -0,0 +1,125 @@
+package devices
+
+import (
+	"github.com/gin-gonic/gin"
+	"go.uber.org/zap"
+	"server/dao/devices"
+	"server/global"
+	"server/model/common/request"
+	"server/model/common/response"
+	model "server/model/devices"
+	"server/utils"
+)
+
+type CameraApi struct{}
+
+func (cameraApi *CameraApi) CameraList(c *gin.Context) {
+	var pageInfo request.PageInfo
+	err := c.ShouldBindJSON(&pageInfo)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = utils.Verify(pageInfo, utils.PageInfoVerify)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	list, total, err := CameraService.GetCameraInfoList(pageInfo)
+	if err != nil {
+		global.GVA_LOG.Error("获取失败!", zap.Error(err))
+		response.FailWithMessage("获取失败", c)
+		return
+	}
+	response.OkWithDetailed(response.PageResult{
+		List:     list,
+		Total:    total,
+		Page:     pageInfo.Page,
+		PageSize: pageInfo.PageSize,
+	}, "获取成功", c)
+}
+
+func (cameraApi *CameraApi) DelCamera(c *gin.Context) {
+	var reqId request.GetById
+	err := c.ShouldBindJSON(&reqId)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = utils.Verify(reqId, utils.IdVerify)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+
+	err = CameraService.DelCamera(reqId.ID)
+	if err != nil {
+		global.GVA_LOG.Error("删除失败!", zap.Error(err))
+		response.FailWithMessage("删除失败", c)
+		return
+	}
+	response.OkWithMessage("删除成功", c)
+}
+
+func (cameraApi *CameraApi) AddCamera(c *gin.Context) {
+	var ca model.ReqCamera
+	err := c.ShouldBindJSON(&ca)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	camera := devices.Camera{
+		CameraName:    ca.CameraName,
+		CameraCode:    ca.CameraCode,
+		CameraType:    ca.CameraType,
+		GatewayId:     ca.GatewayID,
+		CameraBrand:   ca.CameraBrand,
+		CameraModel:   ca.CameraModel,
+		IPAddress:     ca.IpAddress,
+		InstallTime:   ca.InstallTime,
+		Shunt:         ca.Shunt,
+		ShuntDescribe: ca.ShuntDescribe,
+	}
+	err = CameraService.AddCamera(camera)
+	if err != nil {
+		global.GVA_LOG.Error(err.Error(), zap.Error(err))
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	response.OkWithMessage("添加成功", c)
+}
+
+func (cameraApi *CameraApi) UpdateCamera(c *gin.Context) {
+	var ca model.ReqCamera
+	err := c.ShouldBindJSON(&ca)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = utils.Verify(ca, utils.IdVerify)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+
+	camera := devices.Camera{
+		ID:            ca.ID,
+		CameraName:    ca.CameraName,
+		CameraCode:    ca.CameraCode,
+		CameraType:    ca.CameraType,
+		GatewayId:     ca.GatewayID,
+		CameraBrand:   ca.CameraBrand,
+		CameraModel:   ca.CameraModel,
+		IPAddress:     ca.IpAddress,
+		InstallTime:   ca.InstallTime,
+		Shunt:         ca.Shunt,
+		ShuntDescribe: ca.ShuntDescribe,
+	}
+	err = CameraService.UpdateCamera(camera)
+	if err != nil {
+		global.GVA_LOG.Error("设置失败!", zap.Error(err))
+		response.FailWithMessage("设置失败", c)
+		return
+	}
+	response.OkWithMessage("设置成功", c)
+}

+ 110 - 0
server/api/v1/devices/dev_gateway.go

@@ -1 +1,111 @@
 package devices
+
+import (
+	"github.com/gin-gonic/gin"
+	"go.uber.org/zap"
+	"server/dao/devices"
+	"server/global"
+	"server/model/common/request"
+	"server/model/common/response"
+	model "server/model/devices"
+	"server/utils"
+)
+
+type GateWayApi struct{}
+
+func (g *GateWayApi) GateWayList(c *gin.Context) {
+	var pageInfo request.PageInfo
+	err := c.ShouldBindJSON(&pageInfo)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = utils.Verify(pageInfo, utils.PageInfoVerify)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	list, total, err := GateWayService.GetGateWayInfoList(pageInfo)
+	if err != nil {
+		global.GVA_LOG.Error("获取失败!", zap.Error(err))
+		response.FailWithMessage("获取失败", c)
+		return
+	}
+	response.OkWithDetailed(response.PageResult{
+		List:     list,
+		Total:    total,
+		Page:     pageInfo.Page,
+		PageSize: pageInfo.PageSize,
+	}, "获取成功", c)
+}
+func (g *GateWayApi) AddGateway(c *gin.Context) {
+	var w model.ReqGateway
+	err := c.ShouldBindJSON(&w)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	gateWay := devices.GateWay{GatewayName: w.GatewayName, GatewayAddress: w.GatewayAddress, GatewayCode: w.GatewayCode, GatewayBrand: w.GatewayBrand, GatewayModel: w.GatewayModel, IpAddress: w.IpAddress, InstallTime: w.InstallTime}
+	err = GateWayService.AddGateway(gateWay)
+	if err != nil {
+		global.GVA_LOG.Error(err.Error(), zap.Error(err))
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	response.OkWithMessage("添加成功", c)
+}
+
+func (g *GateWayApi) UpdateGateway(c *gin.Context) {
+	var w model.ReqGateway
+	err := c.ShouldBindJSON(&w)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = utils.Verify(w, utils.IdVerify)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+
+	gateWay := devices.GateWay{ID: w.ID, GatewayName: w.GatewayName, GatewayAddress: w.GatewayAddress, GatewayCode: w.GatewayCode, GatewayBrand: w.GatewayBrand, GatewayModel: w.GatewayModel, IpAddress: w.IpAddress, InstallTime: w.InstallTime}
+	err = GateWayService.UpdateGateway(gateWay)
+	if err != nil {
+		global.GVA_LOG.Error("设置失败!", zap.Error(err))
+		response.FailWithMessage("设置失败", c)
+		return
+	}
+	response.OkWithMessage("设置成功", c)
+}
+
+func (g *GateWayApi) DelGateway(c *gin.Context) {
+	var reqId request.GetById
+	err := c.ShouldBindJSON(&reqId)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = utils.Verify(reqId, utils.IdVerify)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+
+	err = GateWayService.DelGateway(reqId.ID)
+	if err != nil {
+		global.GVA_LOG.Error("删除失败!", zap.Error(err))
+		response.FailWithMessage("删除失败", c)
+		return
+	}
+	response.OkWithMessage("删除成功", c)
+}
+
+func (g *GateWayApi) PublicGateway(c *gin.Context) {
+	list, err := GateWayService.PublicGateway()
+	if err != nil {
+		global.GVA_LOG.Error("获取失败!", zap.Error(err))
+		response.FailWithMessage("获取失败", c)
+		return
+	}
+	response.OkWithDetailed(gin.H{"pubGateway": list}, "获取成功", c)
+}

+ 137 - 0
server/api/v1/devices/dev_screens.go

@@ -0,0 +1,137 @@
+package devices
+
+import (
+	"github.com/gin-gonic/gin"
+	"go.uber.org/zap"
+	"server/dao/devices"
+	"server/global"
+	"server/model/common/request"
+	"server/model/common/response"
+	model "server/model/devices"
+	"server/utils"
+)
+
+type ScreensApi struct{}
+
+func (s *ScreensApi) QueryScreensParms(c *gin.Context) {
+	list, err := ScreensService.QueryScreensParms()
+	if err != nil {
+		global.GVA_LOG.Error("获取屏参失败!", zap.Error(err))
+		response.FailWithMessage("获取失败", c)
+		return
+	}
+	response.OkWithDetailed(list, "获取成功", c)
+}
+
+func (s *ScreensApi) ScreensList(c *gin.Context) {
+	var pageInfo request.PageInfo
+	err := c.ShouldBindJSON(&pageInfo)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = utils.Verify(pageInfo, utils.PageInfoVerify)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	list, total, err := ScreensService.GetScreensInfoList(pageInfo)
+	if err != nil {
+		global.GVA_LOG.Error("获取失败!", zap.Error(err))
+		response.FailWithMessage("获取失败", c)
+		return
+	}
+	response.OkWithDetailed(response.PageResult{
+		List:     list,
+		Total:    total,
+		Page:     pageInfo.Page,
+		PageSize: pageInfo.PageSize,
+	}, "获取成功", c)
+}
+
+func (s *ScreensApi) DelScreens(c *gin.Context) {
+	var reqId request.GetById
+	err := c.ShouldBindJSON(&reqId)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = utils.Verify(reqId, utils.IdVerify)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+
+	err = ScreensService.DelScreens(reqId.ID)
+	if err != nil {
+		global.GVA_LOG.Error("删除失败!", zap.Error(err))
+		response.FailWithMessage("删除失败", c)
+		return
+	}
+	response.OkWithMessage("删除成功", c)
+}
+
+func (s *ScreensApi) AddScreens(c *gin.Context) {
+	var sc model.ReqScreens
+	err := c.ShouldBindJSON(&sc)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	screens := devices.Screens{
+		ScreensName:   sc.ScreensName,
+		ScreensCode:   sc.ScreensCode,
+		ScreensBrand:  sc.ScreensBrand,
+		ScreensModel:  sc.ScreensModel,
+		IPAddress:     sc.IpAddress,
+		GatewayId:     sc.GatewayID,
+		ResolutionId:  sc.ResolutionId,
+		ScreensSizeId: sc.ScreensSizeId,
+		Shunt:         sc.Shunt,
+		ShuntDescribe: sc.ShuntDescribe,
+		InstallTime:   sc.InstallTime,
+	}
+	err = ScreensService.AddScreens(screens)
+	if err != nil {
+		global.GVA_LOG.Error(err.Error(), zap.Error(err))
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	response.OkWithMessage("添加成功", c)
+}
+
+func (s *ScreensApi) UpdateScreens(c *gin.Context) {
+	var sc model.ReqScreens
+	err := c.ShouldBindJSON(&sc)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+	err = utils.Verify(sc, utils.IdVerify)
+	if err != nil {
+		response.FailWithMessage(err.Error(), c)
+		return
+	}
+
+	screens := devices.Screens{
+		ID:            sc.ID,
+		ScreensName:   sc.ScreensName,
+		ScreensCode:   sc.ScreensCode,
+		ScreensBrand:  sc.ScreensBrand,
+		ScreensModel:  sc.ScreensModel,
+		IPAddress:     sc.IpAddress,
+		GatewayId:     sc.GatewayID,
+		ResolutionId:  sc.ResolutionId,
+		ScreensSizeId: sc.ScreensSizeId,
+		Shunt:         sc.Shunt,
+		ShuntDescribe: sc.ShuntDescribe,
+		InstallTime:   sc.InstallTime,
+	}
+	err = ScreensService.UpdateScreens(screens)
+	if err != nil {
+		global.GVA_LOG.Error("设置失败!", zap.Error(err))
+		response.FailWithMessage("设置失败", c)
+		return
+	}
+	response.OkWithMessage("设置成功", c)
+}

+ 15 - 0
server/api/v1/devices/enter.go

@@ -0,0 +1,15 @@
+package devices
+
+import "server/service"
+
+type ApiGroup struct {
+	GateWayApi
+	CameraApi
+	ScreensApi
+}
+
+var (
+	GateWayService = service.ServiceGroupApp.DevicesServiceGroup.GateWayService
+	CameraService  = service.ServiceGroupApp.DevicesServiceGroup.CameraService
+	ScreensService = service.ServiceGroupApp.DevicesServiceGroup.ScreensService
+)

+ 2 - 0
server/api/v1/enter.go

@@ -1,6 +1,7 @@
 package v1
 
 import (
+	"server/api/v1/devices"
 	"server/api/v1/example"
 	"server/api/v1/system"
 )
@@ -8,6 +9,7 @@ import (
 type ApiGroup struct {
 	SystemApiGroup  system.ApiGroup
 	ExampleApiGroup example.ApiGroup
+	DevicesApiGroup devices.ApiGroup
 }
 
 var ApiGroupApp = new(ApiGroup)

+ 2 - 2
server/conf/camera.json

@@ -2,7 +2,7 @@
   "Ffmpeg": "ffmpeg.exe",
   "dev": [
     {
-      "Code": "SXT4301024MKRQ5",
+      "Code": "SXT-11111111",
       "IP": "192.168.110.4",
       "Name": "宇视测试球机",
       "Brand": "UNIVIEW",
@@ -16,7 +16,7 @@
       "Gb28181": true
     },
     {
-      "Code": "SXT4301024MKRQ6",
+      "Code": "SXT-1KGEK40UCW",
       "IP": "192.168.110.14",
       "Name": "宇视测试枪机",
       "Brand": "UNIVIEW",

+ 1 - 1
server/config.yaml

@@ -201,7 +201,7 @@ system:
     db-type: mysql
     oss-type: local
     router-prefix: ""
-    addr: 9999
+    addr: 8888
     iplimit-count: 15000
     iplimit-time: 3600
     use-multipoint: false

+ 96 - 0
server/dao/devices/dev_camera.go

@@ -0,0 +1,96 @@
+package devices
+
+import (
+	"gorm.io/gorm"
+	"server/global"
+	"time"
+)
+
+type Camera struct {
+	ID            int            `gorm:"primarykey" json:"ID"`                  //主键ID
+	CameraName    string         `gorm:"type:varchar(64)" json:"cameraName"`    //设备名称
+	CameraCode    string         `gorm:"type:varchar(64)" json:"cameraCode"`    //设备编码
+	CameraType    int            `gorm:"type:int" json:"cameraType"`            //摄像机类型 0=球机,1=枪机
+	GatewayId     int            `gorm:"type:int" json:"gatewayId"`             //所属网关
+	CameraBrand   string         `gorm:"type:varchar(60)" json:"cameraBrand"`   //摄像头品牌
+	CameraModel   string         `gorm:"type:varchar(60)" json:"cameraModel"`   //摄像头型号
+	IPAddress     string         `gorm:"type:varchar(40)" json:"ipAddress"`     //IP地址
+	InstallTime   time.Time      `gorm:"type:date" json:"installTime"`          //安装时间
+	Shunt         int            `gorm:"type:int" json:"shunt"`                 //所属分路 1主路,2支路
+	ShuntDescribe string         `gorm:"type:varchar(60)" json:"shuntDescribe"` //分路描述
+	IsDeleted     gorm.DeletedAt `gorm:"default:null" json:"isDeleted"`         //是否删除
+	Status        int            `gorm:"type:int;default:1" json:"status"`      //在线状态 0=在线,1=离线
+
+	GateWay GateWay `gorm:"foreignkey:GatewayId"`
+}
+
+func (Camera) TableName() string {
+	return "dev_camera"
+}
+
+func (c Camera) IsExistedByCode() error {
+	err := global.GVA_DB.Model(&Camera{}).Where("camera_code = ?", c.CameraCode).First(&c).Error
+	return err
+}
+
+func (c Camera) AddScreens() error {
+	err := global.GVA_DB.Model(&Camera{}).Create(&c).Error
+	return err
+}
+
+func (c Camera) DelCamera(id int) error {
+	err := global.GVA_DB.Model(&c).Where("id = ?", id).Delete(&c).Error
+	return err
+}
+
+func (c Camera) UpdateCamera() error {
+	err := global.GVA_DB.Model(&c).
+		Select("camera_name", "camera_code", "camera_type", "gateway_id", "camera_brand", "camera_model", "ip_address", "install_time", "shunt", "shunt_describe").
+		Where("id=?", c.ID).
+		Updates(map[string]interface{}{
+			"camera_name":    c.CameraName,
+			"camera_code":    c.CameraCode,
+			"camera_type":    c.CameraType,
+			"gateway_id":     c.GatewayId,
+			"camera_brand":   c.CameraBrand,
+			"camera_model":   c.CameraModel,
+			"ip_address":     c.IPAddress,
+			"install_time":   c.InstallTime,
+			"shunt":          c.Shunt,
+			"shunt_describe": c.ShuntDescribe,
+		}).Error
+	return err
+}
+
+func QueryCameraInfoList(limit, offset int, keyword, shunt string) (cameraList []Camera, total int64, err error) {
+	db := global.GVA_DB.Model(&Camera{})
+	if keyword != "" {
+		db.Where("camera_name like ? or camera_code like ?", "%"+keyword+"%", "%"+keyword+"%")
+	}
+	if shunt != "" {
+		db.Where("shunt = ?", shunt)
+	}
+	err = db.Count(&total).Error
+	if err != nil {
+		return
+	}
+	err = db.Limit(limit).Offset(offset).Preload("GateWay").Find(&cameraList).Error
+	return
+}
+
+func QueryCameraToDetail(id int) (cameraList []Camera, err error) {
+	db := global.GVA_DB.Model(&Camera{})
+	err = db.Where("gateway_id = ?", id).Find(&cameraList).Error
+	return
+}
+
+func UpdateCameraStatus(code string, status int) error {
+	var camera Camera
+	err := global.GVA_DB.Model(&camera).
+		Select("status").
+		Where("camera_code = ?", code).
+		Updates(map[string]interface{}{
+			"status": status,
+		}).Error
+	return err
+}

+ 64 - 1
server/dao/devices/dev_gateway.go

@@ -1,9 +1,72 @@
 package devices
 
+import (
+	"gorm.io/gorm"
+	"server/global"
+	"time"
+)
+
 type GateWay struct {
-	ID uint `gorm:"primarykey" json:"ID"` //主键ID
+	ID             int            `gorm:"primary_key" json:"id"`                   //编号
+	GatewayName    string         `gorm:"type:varchar(64)"  json:"gatewayName"`    //网关名称
+	GatewayAddress string         `gorm:"type:varchar(64)"  json:"gatewayAddress"` //网关地址
+	GatewayCode    string         `gorm:"type:varchar(60)" json:"gatewayCode"`     //设备编号
+	GatewayBrand   string         `gorm:"type:varchar(60)" json:"gatewayBrand"`    //网关品牌
+	GatewayModel   string         `gorm:"type:varchar(60)" json:"gatewayModel"`    //网关型号
+	IpAddress      string         `gorm:"type:varchar(50)" json:"ipAddress"`       //IP地址
+	InstallTime    time.Time      `gorm:"type:date" json:"installTime"`            //安装时间
+	IsDeleted      gorm.DeletedAt `gorm:"default:null" json:"isDeleted"`           //是否删除
+	Status         int            `gorm:"type:int;default:1" json:"status"`        //在线状态 0=在线,1=离线
 }
 
 func (GateWay) TableName() string {
 	return "dev_gateway"
 }
+
+func QueryGateWayInfoList(limit, offset int, keyword string) (gatewayList []GateWay, total int64, err error) {
+	db := global.GVA_DB.Model(&GateWay{})
+	if keyword != "" {
+		db.Where("gateway_name like ? or gateway_code like ?", "%"+keyword+"%", "%"+keyword+"%")
+	}
+	err = db.Count(&total).Error
+	if err != nil {
+		return
+	}
+	err = db.Limit(limit).Offset(offset).Find(&gatewayList).Error
+	return
+}
+
+func (g GateWay) IsExistedByCode() error {
+	err := global.GVA_DB.Model(&GateWay{}).Where("gateway_code = ?", g.GatewayCode).First(&g).Error
+	return err
+}
+
+func (g GateWay) AddGateway() error {
+	err := global.GVA_DB.Model(&GateWay{}).Create(&g).Error
+	return err
+}
+
+func (g GateWay) UpdateGateway() error {
+	err := global.GVA_DB.Model(&g).
+		Select("gateway_name", "gateway_address", "gateway_brand", "gateway_model", "ip_address", "install_time").
+		Where("id=?", g.ID).
+		Updates(map[string]interface{}{
+			"gateway_name":    g.GatewayName,
+			"gateway_address": g.GatewayAddress,
+			"gateway_brand":   g.GatewayBrand,
+			"gateway_model":   g.GatewayModel,
+			"ip_address":      g.IpAddress,
+			"install_time":    g.InstallTime,
+		}).Error
+	return err
+}
+
+func (g GateWay) DelGateway(id int) error {
+	err := global.GVA_DB.Model(&g).Where("id = ?", id).Delete(&g).Error
+	return err
+}
+
+func (g GateWay) PublicGateway() (gatewayList []GateWay, err error) {
+	err = global.GVA_DB.Model(&GateWay{}).Select("id", "gateway_name").Find(&gatewayList).Error
+	return
+}

+ 87 - 0
server/dao/devices/dev_screens.go

@@ -0,0 +1,87 @@
+package devices
+
+import (
+	"gorm.io/gorm"
+	"server/global"
+	"time"
+)
+
+type Screens struct {
+	ID            int            `gorm:"primarykey" json:"ID"`                  //主键ID
+	ScreensName   string         `gorm:"type:varchar(64)" json:"screensName"`   //设备名称
+	ScreensCode   string         `gorm:"type:varchar(64)" json:"screensCode"`   //设备编码
+	GatewayId     int            `gorm:"type:int" json:"gatewayId"`             //所属网关
+	ScreensBrand  string         `gorm:"type:varchar(60)" json:"screensBrand"`  //屏幕品牌
+	ScreensModel  string         `gorm:"type:varchar(60)" json:"screensModel"`  //屏幕型号
+	IPAddress     string         `gorm:"type:varchar(40)" json:"ipAddress"`     //IP地址
+	InstallTime   time.Time      `gorm:"type:date" json:"installTime"`          //安装时间
+	Shunt         int            `gorm:"type:int" json:"shunt"`                 //所属分路 1主路,2支路
+	ShuntDescribe string         `gorm:"type:varchar(60)" json:"shuntDescribe"` //分路描述
+	ResolutionId  int            `gorm:"type:int" json:"resolutionId"`          //分辨率
+	ScreensSizeId int            `gorm:"type:int" json:"screensSizeId"`         //信息屏尺寸
+	IsDeleted     gorm.DeletedAt `gorm:"default:null" json:"isDeleted"`         //是否删除
+	Status        int            `gorm:"type:int;default:1" json:"status"`      //在线状态 0=在线,1=离线
+
+	GateWay     GateWay     `gorm:"foreignkey:GatewayId"`
+	Resolution  Resolution  `gorm:"foreignkey:ResolutionId"`
+	ScreensSize ScreensSize `gorm:"foreignkey:ScreensSizeId"`
+}
+
+func (Screens) TableName() string {
+	return "dev_screens"
+}
+
+func (s Screens) DelScreens(id int) error {
+	err := global.GVA_DB.Model(&s).Where("id = ?", id).Delete(&s).Error
+	return err
+}
+func (s Screens) IsExistedByCode() error {
+	err := global.GVA_DB.Model(&Screens{}).Where("screens_code = ?", s.ScreensCode).First(&s).Error
+	return err
+}
+func (s Screens) AddScreens() error {
+	err := global.GVA_DB.Model(&Screens{}).Create(&s).Error
+	return err
+}
+
+func (s Screens) UpdateScreens() error {
+	err := global.GVA_DB.Model(&s).
+		Select("screens_name", "screens_code", "gateway_id", "screens_brand", "screens_model", "ip_address", "install_time", "shunt", "shunt_describe", "resolution_id", "screens_size_id").
+		Where("id=?", s.ID).
+		Updates(map[string]interface{}{
+			"screens_name":    s.ScreensName,
+			"screens_code":    s.ScreensCode,
+			"gateway_id":      s.GatewayId,
+			"screens_brand":   s.ScreensBrand,
+			"screens_model":   s.ScreensModel,
+			"ip_address":      s.IPAddress,
+			"install_time":    s.InstallTime,
+			"shunt":           s.Shunt,
+			"shunt_describe":  s.ShuntDescribe,
+			"resolution_id":   s.ResolutionId,
+			"screens_size_id": s.ScreensSizeId,
+		}).Error
+	return err
+}
+
+func QueryScreensInfoList(limit, offset int, keyword, shunt string) (screensList []Screens, total int64, err error) {
+	db := global.GVA_DB.Model(&Screens{})
+	if keyword != "" {
+		db.Where("screens_name like ? or screens_code like ?", "%"+keyword+"%", "%"+keyword+"%")
+	}
+	if shunt != "" {
+		db.Where("shunt = ?", shunt)
+	}
+	err = db.Count(&total).Error
+	if err != nil {
+		return
+	}
+	err = db.Limit(limit).Offset(offset).Preload("GateWay").Preload("Resolution").Preload("ScreensSize").Find(&screensList).Error
+	return
+}
+
+func QueryScreensToDetail(id int) (screensList []Screens, err error) {
+	db := global.GVA_DB.Model(&Screens{})
+	err = db.Where("gateway_id = ?", id).Find(&screensList).Error
+	return
+}

+ 34 - 0
server/dao/devices/screens_parameter.go

@@ -0,0 +1,34 @@
+package devices
+
+import "server/global"
+
+// 分辨率
+type Resolution struct {
+	ID    int    `gorm:"primarykey" json:"ID"`          //主键ID
+	Price string `gorm:"type:varchar(64)" json:"price"` //分辨率
+}
+
+func (Resolution) TableName() string {
+	return "screens_resolution"
+}
+
+// 屏幕尺寸
+type ScreensSize struct {
+	ID   int    `gorm:"primarykey" json:"ID"`         //主键ID
+	Size string `gorm:"type:varchar(64)" json:"size"` //尺寸
+}
+
+func (ScreensSize) TableName() string {
+	return "screens_screens_size"
+}
+
+func (r Resolution) GetResolution() ([]Resolution, error) {
+	var resolution []Resolution
+	err := global.GVA_DB.Model(&r).Find(&resolution).Error
+	return resolution, err
+}
+func (s ScreensSize) GetScreensSize() ([]ScreensSize, error) {
+	var sreensSize []ScreensSize
+	err := global.GVA_DB.Model(&s).Find(&sreensSize).Error
+	return sreensSize, err
+}

+ 5 - 0
server/initialize/gorm.go

@@ -2,6 +2,7 @@ package initialize
 
 import (
 	"os"
+	"server/dao/devices"
 	example2 "server/dao/example"
 	"server/dao/system"
 
@@ -47,6 +48,10 @@ func RegisterTables() {
 		example.ExaFile{},
 		example.ExaFileChunk{},
 		example2.ExaFileUploadAndDownload{},
+
+		devices.GateWay{},
+		devices.Camera{},
+		devices.Screens{}, devices.Resolution{}, devices.ScreensSize{}, //屏幕以及一些屏参
 	)
 	if err != nil {
 		global.GVA_LOG.Error("register table failed", zap.Error(err))

+ 6 - 0
server/initialize/router.go

@@ -42,6 +42,7 @@ func Routers() *gin.Engine {
 	InstallPlugin(Router) // 安装插件
 	systemRouter := router.RouterGroupApp.System
 	exampleRouter := router.RouterGroupApp.Example
+	devicesRouter := router.RouterGroupApp.Devices
 	// 如果想要不使用nginx代理前端网页,可以修改 web/.env.production 下的
 	// VUE_APP_BASE_API = /
 	// VUE_APP_BASE_PATH = http://localhost
@@ -85,6 +86,11 @@ func Routers() *gin.Engine {
 		systemRouter.InitAuthorityBtnRouterRouter(PrivateGroup)  // 字典详情管理
 
 		exampleRouter.InitFileUploadAndDownloadRouter(PrivateGroup)
+
+		devicesRouter.InitGateWayRouter(PrivateGroup, PublicGroup) //注册网关路由
+		devicesRouter.InitCameraRouter(PrivateGroup)               //注册摄像头路由
+		devicesRouter.InitScreensRouter(PrivateGroup, PublicGroup) //注册LED屏路由
+
 	}
 
 	global.GVA_LOG.Info("router register success")

+ 2 - 1
server/initialize/tasks.go

@@ -7,7 +7,8 @@ import (
 
 func TimeTasks() {
 	c := cron.New()
-	_ = c.AddFunc("*/5 * * * * ?", func() {
+	//每五分钟监测状态
+	_ = c.AddFunc("0 */5 * * * ?", func() {
 		//检查摄像头是否在线
 		camera.TestCameraOnline(camera.CameraDevices)
 	})

+ 2 - 1
server/model/common/request/common.go

@@ -4,7 +4,8 @@ package request
 type PageInfo struct {
 	Page     int    `json:"page" form:"page"`         // 页码
 	PageSize int    `json:"pageSize" form:"pageSize"` // 每页大小
-	Keyword  string `json:"keyword" form:"keyword"`   //关键字
+	Keyword  string `json:"keyword" form:"keyword"`   //关键字1
+	Shunt    string `json:"shunt" form:"shunt"`       //关键字2
 }
 
 // GetById Find by id structure

+ 17 - 0
server/model/devices/dev_camera.go

@@ -0,0 +1,17 @@
+package devices
+
+import "time"
+
+type ReqCamera struct {
+	ID            int       `json:"id"`            //ID
+	CameraName    string    `json:"cameraName"`    //名称
+	CameraCode    string    `json:"cameraCode"`    //设备编号
+	CameraType    int       `json:"cameraType"`    //摄像头类型
+	CameraBrand   string    `json:"cameraBrand"`   //品牌
+	CameraModel   string    `json:"cameraModel"`   //型号
+	IpAddress     string    `json:"ipAddress"`     //IP地址
+	GatewayID     int       `json:"gatewayId"`     //所属网关
+	Shunt         int       `json:"shunt"`         //所属分路 1主路,2支路
+	ShuntDescribe string    `json:"shuntDescribe"` //分路描述
+	InstallTime   time.Time `json:"installTime"`   //安装时间
+}

+ 29 - 0
server/model/devices/dev_gateway.go

@@ -0,0 +1,29 @@
+package devices
+
+import (
+	"server/dao/devices"
+	"time"
+)
+
+type GatewayDetails struct {
+	Gateway devices.GateWay `json:"gateway"`
+	//Camera  []devices.Camera  `json:"cameraList"`
+	//Screens []devices.Screens `json:"screensList"`
+	RelationDev RelationDev `json:"relationDev"`
+}
+
+type RelationDev struct {
+	Camera  []devices.Camera  `json:"cameraList"`
+	Screens []devices.Screens `json:"screensList"`
+}
+
+type ReqGateway struct {
+	ID             int       `json:"id"`             //ID
+	GatewayName    string    `json:"gatewayName"`    //网关名称
+	GatewayAddress string    `json:"gatewayAddress"` //网关地址
+	GatewayCode    string    `json:"gatewayCode"`    //设备编号
+	GatewayBrand   string    `json:"gatewayBrand"`   //网关品牌
+	GatewayModel   string    `json:"gatewayModel"`   //网关型号
+	IpAddress      string    `json:"ipAddress"`      //IP地址
+	InstallTime    time.Time `json:"installTime"`    //安装时间
+}

+ 27 - 0
server/model/devices/dev_screens.go

@@ -0,0 +1,27 @@
+package devices
+
+import (
+	"server/dao/devices"
+	"time"
+)
+
+type RspParams struct {
+	Resolution  []devices.Resolution  `json:"resolution"`
+	ScreensSize []devices.ScreensSize `json:"screensSize"`
+	PubGateway  []devices.GateWay     `json:"pubGateway"`
+}
+
+type ReqScreens struct {
+	ID            int       `json:"id"`            //ID
+	ScreensName   string    `json:"screensName"`   //名称
+	ScreensCode   string    `json:"screensCode"`   //设备编号
+	ScreensBrand  string    `json:"screensBrand"`  //品牌
+	ScreensModel  string    `json:"screensModel"`  //型号
+	IpAddress     string    `json:"ipAddress"`     //IP地址
+	GatewayID     int       `json:"gatewayId"`     //所属网关
+	ResolutionId  int       `json:"resolutionId"`  //分辨率
+	ScreensSizeId int       `json:"screensSizeId"` //屏幕尺寸
+	Shunt         int       `json:"shunt"`         //所属分路 1主路,2支路
+	ShuntDescribe string    `json:"shuntDescribe"` //分路描述
+	InstallTime   time.Time `json:"installTime"`   //安装时间
+}

+ 23 - 0
server/router/devices/dev_camera.go

@@ -0,0 +1,23 @@
+package devices
+
+import (
+	"github.com/gin-gonic/gin"
+	v1 "server/api/v1"
+	"server/middleware"
+)
+
+type CameraRouter struct{}
+
+func (c *CameraRouter) InitCameraRouter(Router *gin.RouterGroup) {
+	cameraRouter := Router.Group("camera").Use(middleware.OperationRecord())
+	cameraRouterWithoutRecord := Router.Group("camera")
+	baseApi := v1.ApiGroupApp.DevicesApiGroup.CameraApi
+	{
+		cameraRouter.POST("addCamera", baseApi.AddCamera)      // 添加摄像头
+		cameraRouter.PUT("updateCamera", baseApi.UpdateCamera) // 编辑摄像头
+		cameraRouter.DELETE("delCamera", baseApi.DelCamera)    // 删除摄像头
+	}
+	{
+		cameraRouterWithoutRecord.POST("getCameraList", baseApi.CameraList) // 分页获取网关列表
+	}
+}

+ 29 - 0
server/router/devices/dev_gateway.go

@@ -0,0 +1,29 @@
+package devices
+
+import (
+	"github.com/gin-gonic/gin"
+	v1 "server/api/v1"
+	"server/middleware"
+)
+
+type GateWayRouter struct{}
+
+func (g *GateWayRouter) InitGateWayRouter(Router *gin.RouterGroup, RouterPub *gin.RouterGroup) {
+	gatewayRouter := Router.Group("gateway").Use(middleware.OperationRecord())
+	gatewayRouterWithoutRecord := Router.Group("gateway")
+
+	apiPublicRouterWithoutRecord := RouterPub.Group("gateway")
+	baseApi := v1.ApiGroupApp.DevicesApiGroup.GateWayApi
+	{
+		gatewayRouter.POST("addGateway", baseApi.AddGateway)       // 增加网关
+		gatewayRouter.POST("updateGateway", baseApi.UpdateGateway) // 编辑网关
+		gatewayRouter.DELETE("delGateway", baseApi.DelGateway)     // 删除网关
+	}
+	{
+		gatewayRouterWithoutRecord.POST("getGateWayList", baseApi.GateWayList) // 分页获取网关列表
+		//gatewayRouterWithoutRecord.GET("getUserInfo", baseApi.GetUserInfo)  // 获取自身信息
+	}
+	{
+		apiPublicRouterWithoutRecord.GET("getPublicGateway", baseApi.PublicGateway)
+	}
+}

+ 28 - 0
server/router/devices/dev_screens.go

@@ -0,0 +1,28 @@
+package devices
+
+import (
+	"github.com/gin-gonic/gin"
+	v1 "server/api/v1"
+	"server/middleware"
+)
+
+type ScreensRouter struct{}
+
+func (l *ScreensRouter) InitScreensRouter(Router *gin.RouterGroup, RouterPub *gin.RouterGroup) {
+	screensRouter := Router.Group("screens").Use(middleware.OperationRecord())
+	screensRouterWithoutRecord := Router.Group("screens")
+
+	apiPublicRouterWithoutRecord := RouterPub.Group("screens")
+	baseApi := v1.ApiGroupApp.DevicesApiGroup.ScreensApi
+	{
+		screensRouter.PUT("updateScreens", baseApi.UpdateScreens) //编辑显示屏
+		screensRouter.POST("addScreens", baseApi.AddScreens)      //添加显示屏
+		screensRouter.DELETE("delScreens", baseApi.DelScreens)    // 删除显示屏
+	}
+	{
+		screensRouterWithoutRecord.POST("getScreensList", baseApi.ScreensList) // 分页获取网关列表
+	}
+	{
+		apiPublicRouterWithoutRecord.GET("screensParms", baseApi.QueryScreensParms) //获取屏参
+	}
+}

+ 7 - 0
server/router/devices/enter.go

@@ -0,0 +1,7 @@
+package devices
+
+type RouterGroup struct {
+	GateWayRouter
+	CameraRouter
+	ScreensRouter
+}

+ 2 - 0
server/router/enter.go

@@ -1,6 +1,7 @@
 package router
 
 import (
+	"server/router/devices"
 	"server/router/example"
 	"server/router/system"
 )
@@ -8,6 +9,7 @@ import (
 type RouterGroup struct {
 	System  system.RouterGroup
 	Example example.RouterGroup
+	Devices devices.RouterGroup
 }
 
 var RouterGroupApp = new(RouterGroup)

+ 43 - 0
server/service/devices/dev_camera.go

@@ -0,0 +1,43 @@
+package devices
+
+import (
+	"errors"
+	"gorm.io/gorm"
+	"server/dao/devices"
+	"server/model/common/request"
+	"server/utils/logger"
+)
+
+type CameraService struct{}
+
+func (cameraService *CameraService) GetCameraInfoList(info request.PageInfo) (list interface{}, total int64, err error) {
+	limit := info.PageSize
+	offset := info.PageSize * (info.Page - 1)
+	keyword := info.Keyword
+	shunt := info.Shunt
+
+	userList, total, err := devices.QueryCameraInfoList(limit, offset, keyword, shunt)
+
+	return userList, total, err
+}
+
+func (cameraService *CameraService) AddCamera(camera devices.Camera) error {
+	err := camera.IsExistedByCode()
+	if !errors.Is(err, gorm.ErrRecordNotFound) {
+		logger.Logger.Errorf("Create IsExistedByCode \n")
+		return errors.New("设备编码已存在!")
+	}
+	err = camera.AddScreens()
+	return err
+}
+
+func (cameraService *CameraService) DelCamera(id int) error {
+	c := devices.Camera{}
+	err := c.DelCamera(id)
+	return err
+}
+
+func (cameraService *CameraService) UpdateCamera(camera devices.Camera) error {
+	err := camera.UpdateCamera()
+	return err
+}

+ 62 - 0
server/service/devices/dev_gateway.go

@@ -1 +1,63 @@
 package devices
+
+import (
+	"errors"
+	"gorm.io/gorm"
+	"server/dao/devices"
+	"server/model/common/request"
+	model "server/model/devices"
+	"server/utils/logger"
+)
+
+type GateWayService struct{}
+
+func (gateWayService *GateWayService) GetGateWayInfoList(info request.PageInfo) (list interface{}, total int64, err error) {
+	limit := info.PageSize
+	offset := info.PageSize * (info.Page - 1)
+	keyword := info.Keyword
+
+	gatewayList, total, err := devices.QueryGateWayInfoList(limit, offset, keyword)
+
+	var details []model.GatewayDetails
+
+	for _, gateWay := range gatewayList {
+		detail := model.GatewayDetails{Gateway: gateWay}
+		screensList, _ := devices.QueryScreensToDetail(gateWay.ID)
+		cameraList, _ := devices.QueryCameraToDetail(gateWay.ID)
+
+		detail.RelationDev.Screens = screensList
+		detail.RelationDev.Camera = cameraList
+
+		details = append(details, detail)
+	}
+
+	return details, total, err
+}
+
+func (gateWayService *GateWayService) AddGateway(way devices.GateWay) error {
+	err := way.IsExistedByCode()
+	if !errors.Is(err, gorm.ErrRecordNotFound) {
+		logger.Logger.Errorf("Create IsExistedByCode \n")
+		return errors.New("设备编码已存在!")
+	}
+
+	err = way.AddGateway()
+	return err
+}
+
+func (gateWayService *GateWayService) UpdateGateway(way devices.GateWay) error {
+	err := way.UpdateGateway()
+	return err
+}
+
+func (gateWayService *GateWayService) DelGateway(id int) error {
+	way := devices.GateWay{}
+	err := way.DelGateway(id)
+	return err
+}
+
+func (gateWayService *GateWayService) PublicGateway() (interface{}, error) {
+	way := devices.GateWay{}
+	list, err := way.PublicGateway()
+	return list, err
+}

+ 59 - 0
server/service/devices/dev_screens.go

@@ -0,0 +1,59 @@
+package devices
+
+import (
+	"errors"
+	"gorm.io/gorm"
+	"server/dao/devices"
+	"server/model/common/request"
+	model "server/model/devices"
+	"server/utils/logger"
+)
+
+type ScreensService struct{}
+
+func (screensService *ScreensService) GetScreensInfoList(info request.PageInfo) (list interface{}, total int64, err error) {
+	limit := info.PageSize
+	offset := info.PageSize * (info.Page - 1)
+	keyword := info.Keyword
+	shunt := info.Shunt
+
+	gatewayList, total, err := devices.QueryScreensInfoList(limit, offset, keyword, shunt)
+
+	return gatewayList, total, err
+}
+
+func (screensService *ScreensService) QueryScreensParms() (list interface{}, err error) {
+	resolution := devices.Resolution{}
+	getResolution, err := resolution.GetResolution()
+
+	screensSize := devices.ScreensSize{}
+	getScreensSize, err := screensSize.GetScreensSize()
+
+	way := devices.GateWay{}
+	gatewayList, err := way.PublicGateway()
+
+	params := model.RspParams{Resolution: getResolution, ScreensSize: getScreensSize, PubGateway: gatewayList}
+
+	return params, err
+}
+
+func (screensService *ScreensService) DelScreens(id int) error {
+	s := devices.Screens{}
+	err := s.DelScreens(id)
+	return err
+}
+
+func (screensService *ScreensService) AddScreens(screens devices.Screens) error {
+	err := screens.IsExistedByCode()
+	if !errors.Is(err, gorm.ErrRecordNotFound) {
+		logger.Logger.Errorf("Create IsExistedByCode \n")
+		return errors.New("设备编码已存在!")
+	}
+	err = screens.AddScreens()
+	return err
+}
+
+func (screensService *ScreensService) UpdateScreens(screens devices.Screens) error {
+	err := screens.UpdateScreens()
+	return err
+}

+ 7 - 0
server/service/devices/enter.go

@@ -0,0 +1,7 @@
+package devices
+
+type ServiceGroup struct {
+	GateWayService
+	CameraService
+	ScreensService
+}

+ 2 - 0
server/service/enter.go

@@ -1,6 +1,7 @@
 package service
 
 import (
+	"server/service/devices"
 	"server/service/example"
 	"server/service/system"
 )
@@ -8,6 +9,7 @@ import (
 type ServiceGroup struct {
 	SystemServiceGroup  system.ServiceGroup
 	ExampleServiceGroup example.ServiceGroup
+	DevicesServiceGroup devices.ServiceGroup
 }
 
 var ServiceGroupApp = new(ServiceGroup)

+ 5 - 3
server/utils/mqtt/mqtt_handle.go

@@ -5,7 +5,9 @@ import (
 	"fmt"
 	"runtime"
 	"runtime/debug"
+	Dev "server/dao/devices"
 	"server/utils/logger"
+	"strconv"
 	"strings"
 	"sync"
 	"time"
@@ -78,9 +80,9 @@ func (o *MqttHandler) Handler() interface{} {
 		}
 		switch topic {
 		case TopicDeviceCamera:
-			fmt.Println("code...", deviceCode)
-			fmt.Println("数据...", m.PayloadString())
-			//TODO 待更新数据库
+			//根据编码修改摄像头状态
+			status, _ := strconv.Atoi(m.PayloadString())
+			Dev.UpdateCameraStatus(deviceCode, status)
 		}
 
 	}

+ 40 - 0
web/src/api/camera.js

@@ -0,0 +1,40 @@
+import service from '@/utils/request'
+
+export const getCameraList = (data) => {
+    return service({
+        url: '/camera/getCameraList',
+        method: 'post',
+        data: data
+    })
+}
+
+export const addCamera = (data) => {
+    return service({
+        url: '/camera/addCamera',
+        method: 'post',
+        data: data
+    })
+}
+
+export const setCameraInfo = (data) => {
+    return service({
+        url: '/camera/updateCamera',
+        method: 'put',
+        data: data
+    })
+}
+
+export const deleteBaseCamera = (data) => {
+    return service({
+        url: '/camera/delCamera',
+        method: 'delete',
+        data: data
+    })
+}
+
+export const getPublicGateway = () => {
+    return service({
+        url: '/gateway/getPublicGateway',
+        method: 'get'
+    })
+}

+ 3 - 3
web/src/api/fileUploadAndDownload.js

@@ -6,10 +6,10 @@ import service from '@/utils/request'
 // @Produce application/json
 // @Param data body modelInterface.PageInfo true "分页获取文件户列表"
 // @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
-// @Router /fileUploadAndDownload/getFileList [post]
-export const getFileList = (data) => {
+// @Router /fileUploadAndDownload/getgatewayList [post]
+export const getgatewayList = (data) => {
   return service({
-    url: '/fileUploadAndDownload/getFileList',
+    url: '/fileUploadAndDownload/getgatewayList',
     method: 'post',
     data
   })

+ 35 - 0
web/src/api/gateway.js

@@ -0,0 +1,35 @@
+import service from '@/utils/request'
+
+export const getGatewayList = (data) => {
+  return service({
+    url: '/gateway/getGateWayList',
+    method: 'post',
+    data: data
+  })
+}
+
+export const addGateway = (data) => {
+  return service({
+    url: '/gateway/addGateway',
+    method: 'post',
+    data: data
+  })
+}
+
+export const setGatewayInfo = (data) => {
+  return service({
+    url: '/gateway/updateGateway',
+    method: 'post',
+    data: data
+  })
+}
+
+export const deleteBaseGateway = (data) => {
+  return service({
+    url: '/gateway/delGateway',
+    method: 'delete',
+    data: data
+  })
+}
+
+

+ 40 - 0
web/src/api/screens.js

@@ -0,0 +1,40 @@
+import service from '@/utils/request'
+
+export const queryscreensParms = () => {
+    return service({
+        url: '/screens/screensParms',
+        method: 'get',
+    })
+}
+
+export const getScreensList = (data) => {
+    return service({
+        url: '/screens/getScreensList',
+        method: 'post',
+        data: data
+    })
+}
+
+export const addScreens = (data) => {
+    return service({
+        url: '/screens/addScreens',
+        method: 'post',
+        data: data
+    })
+}
+
+export const setScreensInfo = (data) => {
+    return service({
+        url: '/screens/updateScreens',
+        method: 'put',
+        data: data
+    })
+}
+
+export const deleteBaseScreens = (data) => {
+    return service({
+        url: '/screens/delScreens',
+        method: 'delete',
+        data: data
+    })
+}

+ 5 - 5
web/src/components/selectFile/selectFile.vue

@@ -6,7 +6,7 @@
       :on-error="uploadError"
       :on-success="uploadSuccess"
       :show-file-list="true"
-      :file-list="fileList"
+      :file-list="gatewayList"
       :limit="limit"
       :accept="accept"
       class="upload-btn"
@@ -46,11 +46,11 @@ const path = ref(import.meta.env.VITE_BASE_API)
 const userStore = useUserStore()
 const fullscreenLoading = ref(false)
 
-const fileList = ref(props.modelValue)
+const gatewayList = ref(props.modelValue)
 
 const emits = defineEmits(['update:modelValue'])
 
-watch(fileList.value, (val) => {
+watch(gatewayList.value, (val) => {
   console.log(val)
   emits('update:modelValue', val)
 })
@@ -58,14 +58,14 @@ watch(fileList.value, (val) => {
 watch(
   () => props.modelValue,
   value => {
-    fileList.value = value
+    gatewayList.value = value
   },
   { immediate: true }
 )
 const uploadSuccess = (res) => {
   const { data } = res
   if (data.file) {
-    fileList.value.push({
+    gatewayList.value.push({
       name: data.file.name,
       url: data.file.url
     })

+ 2 - 2
web/src/components/selectImage/selectImage.vue

@@ -197,7 +197,7 @@
 
 import { getUrl, isVideoExt } from '@/utils/image'
 import { onMounted, ref } from 'vue'
-import { getFileList, editFileName } from '@/api/fileUploadAndDownload'
+import { getgatewayList, editFileName } from '@/api/fileUploadAndDownload'
 import UploadImage from '@/components/upload/image.vue'
 import UploadCommon from '@/components/upload/common.vue'
 import WarningBar from '@/components/warningBar/warningBar.vue'
@@ -321,7 +321,7 @@ const openChooseImg = async() => {
 }
 
 const getImageList = async() => {
-  const res = await getFileList({ page: page.value, pageSize: pageSize.value, ...search.value })
+  const res = await getgatewayList({ page: page.value, pageSize: pageSize.value, ...search.value })
   if (res.code === 0) {
     picList.value = res.data.list
     total.value = res.data.total

+ 478 - 0
web/src/view/devicesAdmin/camera/camera.vue

@@ -0,0 +1,478 @@
+<template>
+  <div>
+    <div class="gva-search-box">
+      <el-form
+          ref="searchForm"
+          :inline="true"
+          :model="searchInfo"
+      >
+        <el-form-item label="名称或编码">
+          <el-input
+              v-model="searchInfo.keyword"
+              placeholder="搜索名称或编码"
+          />
+        </el-form-item>
+        <el-form-item label="所属分路">
+          <el-select v-model="searchInfo.shunt" placeholder="所属分路">
+            <el-option label="主路" value=1></el-option>
+            <el-option label="支路" value=2></el-option>
+          </el-select>
+        </el-form-item>
+
+        <el-form-item>
+          <el-button
+              type="primary"
+              icon="search"
+              @click="onSubmit"
+          >查询</el-button>
+          <el-button
+              icon="refresh"
+              @click="onReset"
+          >重置</el-button>
+        </el-form-item>
+      </el-form>
+    </div>
+    <div class="gva-table-box">
+      <div class="gva-btn-list">
+        <el-button
+            type="primary"
+            icon="plus"
+            @click="add()"
+        >新增</el-button>
+      </div>
+      <el-table
+          :data="tableData"
+          style="width: 100%; margin-bottom: 20px"
+          row-key="id"
+          border
+          :table-layout="'fixed'"
+          :row-class-name="tableRowClassName"
+      >
+        <el-table-column prop="ID" label="#" :width="80"/>
+        <el-table-column prop="shunt" label="所属分路" :width="100">
+          <template #default="scope">
+            {{ scope.row.shunt===1?"主路":scope.row.shunt===2?"支路":"未知" }}
+          </template>
+        </el-table-column>
+        <el-table-column prop="cameraName" label="名称" />
+        <el-table-column prop="cameraCode" label="编码">
+          <template #default="scope">
+            <el-tag effect="light">{{ scope.row.cameraCode }}</el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column prop="cameraBrand" label="品牌" />
+        <el-table-column prop="cameraModel" label="型号"/>
+        <el-table-column prop="cameraType" label="类型">
+          <template #default="scope">
+            {{ scope.row.cameraType === 0?'球机':'枪机' }}
+          </template>
+        </el-table-column>
+        <el-table-column prop="GateWay.gatewayName" label="所属网关"/>
+        <el-table-column prop="status" label="在线状态">
+          <template #default="scope">
+            <div class="onlinebox" :style="{'background': scope.row.status===1 ? 'red':'green' }"></div>
+            <span :style="{ color: scope.row.status === 1 ? 'red' : 'green' }">{{ scope.row.status === 1 ? '离线' : '在线' }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column
+            align="left"
+            fixed="right"
+            label="操作"
+            :width="300"
+        >
+          <template #default="scope">
+            <el-button
+                type="primary"
+                link
+                icon="view"
+                @click="view(scope.row)"
+            >查看</el-button>
+            <el-button
+                type="primary"
+                link
+                icon="edit"
+                @click="editCamera(scope.row)"
+            >编辑</el-button>
+            <el-button
+                type="primary"
+                link
+                icon="delete"
+                @click="deleteCamera(scope.row)"
+            >删除</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+      <div class="gva-pagination">
+        <el-pagination
+            :current-page="page"
+            :page-size="pageSize"
+            :page-sizes="[10, 30, 50, 100]"
+            :total="total"
+            layout="total, sizes, prev, pager, next, jumper"
+            @current-change="handleCurrentChange"
+            @size-change="handleSizeChange"
+        />
+      </div>
+
+      <el-dialog v-model="addCameraDialog" title="摄像头" width="900">
+        <el-form
+            ref="cameraForm"
+            :rules="rules"
+            :model="cameraInfo"
+            label-width="110px"
+            style="padding: 15px"
+        >
+          <el-row>
+            <el-col :span="12">
+              <el-form-item label="摄像头名称:" :inline="false" prop="cameraName">
+                <el-input v-model="cameraInfo.cameraName"></el-input>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="编码:" :inline="false">
+                <el-input disabled v-model="cameraInfo.cameraCode"></el-input>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row>
+            <el-col :span="12">
+              <el-form-item label="品牌:" :inline="false" prop="cameraBrand">
+                <el-input v-model="cameraInfo.cameraBrand"></el-input>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="型号:" :inline="false" prop="cameraModel">
+                <el-input v-model="cameraInfo.cameraModel"></el-input>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row>
+            <el-col :span="12">
+              <el-form-item label="ip地址:" :inline="false" prop="ipAddress">
+                <el-input v-model="cameraInfo.ipAddress"></el-input>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="所属网关:" :inline="false" prop="gatewayId">
+                <el-select v-model="cameraInfo.gatewayId" placeholder="所属网关">
+                  <el-option v-for=" (item) in gatewayList" :label="item.gatewayName" :value="item.id"></el-option>
+                </el-select>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row>
+            <el-col :span="12">
+              <el-form-item label="所属分路:" :inline="false">
+                <el-select v-model="cameraInfo.shunt" placeholder="请选择所属分路">
+                  <el-option label="主路" :value=1></el-option>
+                  <el-option label="支路" :value=2></el-option>
+                </el-select>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="分路描述:" :inline="false">
+                <el-input v-model="cameraInfo.shuntDescribe"></el-input>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row>
+            <el-col :span="12">
+              <el-form-item label="摄像头类型:" :inline="false">
+                <el-select v-model="cameraInfo.cameraType" placeholder="摄像头类型">
+                  <el-option label="球机" :value=0></el-option>
+                  <el-option label="枪机" :value=1></el-option>
+                </el-select>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="安装时间:" :inline="false">
+                <el-date-picker
+                    v-model="cameraInfo.installTime"
+                    type="date"
+                    placeholder="Pick a day"
+                    size="default"
+                />
+              </el-form-item>
+            </el-col>
+          </el-row>
+        </el-form>
+        <template #footer>
+          <div class="dialog-footer">
+            <el-button @click="closeAddCameraDialog">取消</el-button>
+            <el-button type="primary" @click="enterAddCameraDialog">
+              确定
+            </el-button>
+          </div>
+        </template>
+      </el-dialog>
+
+      <el-dialog v-model="viewCameraDialog" title="详情" style="padding: 35px">
+        <el-form
+            :model="cameraInfo"
+            label-width="100px"
+            style="padding: 20px"
+        >
+          <el-row>
+            <el-col :span="12">
+              <el-form-item label="摄像头名称:" :inline="false">
+                {{cameraInfo.cameraName }}
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="编码:" :inline="false">
+                {{cameraInfo.cameraCode }}
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row>
+            <el-col :span="12">
+              <el-form-item label="品牌:" :inline="false">
+                {{cameraInfo.cameraBrand }}
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="型号:" :inline="false">
+                {{cameraInfo.cameraModel }}
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row>
+            <el-col :span="12">
+              <el-form-item label="ip地址:" :inline="false">
+                {{cameraInfo.ipAddress }}
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="所属网关:" :inline="false">
+                {{cameraInfo.GateWay.gatewayName }}
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row>
+            <el-col :span="12">
+              <el-form-item label="所属分路:" :inline="false">
+                <el-tag  effect="dark">{{cameraInfo.shunt===1?"主路":cameraInfo.shunt===2?"支路":"未知"}}</el-tag>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="分路描述:" :inline="false">
+                {{cameraInfo.shuntDescribe }}
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row>
+            <el-col :span="12">
+              <el-form-item label="摄像头类型:" :inline="false">
+                <el-tag effect="dark" type="success">{{ cameraInfo.cameraType === 0?'球机':'枪机' }}</el-tag>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="在线状态:" :inline="false">
+                <div class="onlinebox" :style="{'background': cameraInfo.status===1 ? 'red':'green' }"></div>
+                <span :style="{ color: cameraInfo.status === 1 ? 'red' : 'green' }">{{ cameraInfo.status === 1 ? '离线' : '在线' }}</span>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row>
+            <el-col :span="12">
+              <el-form-item label="安装时间:" :inline="false">
+                {{cameraInfo.installTime }}
+              </el-form-item>
+            </el-col>
+          </el-row>
+        </el-form>
+      </el-dialog>
+    </div>
+  </div>
+</template>
+<script setup>
+import {deleteBaseCamera, getCameraList,getPublicGateway,setCameraInfo,addCamera} from "@/api/camera";
+import { ref} from 'vue'
+import {ElMessage, ElMessageBox} from "element-plus";
+const page = ref(1)
+const total = ref(0)
+const pageSize = ref(10)
+const tableData = ref([])
+const searchInfo = ref({})
+const cameraInfo = ref({})
+const gatewayList = ref([])
+const cameraForm = ref(null)
+const dialogFlag = ref('add')
+const isFlag = ref('')
+const addCameraDialog = ref(false)
+const viewCameraDialog = ref(false)
+
+const rules = ref({
+  cameraName: [
+    { required: true, message: '请输入名称',trigger: 'blur'},
+    { min: 5, message: '最低5位字符', trigger: 'blur' }
+  ],
+  cameraBrand: [
+    { required: true, message: '请填写品牌',trigger: 'blur'},
+  ],
+  cameraModel: [
+    { required: true, message: '请填写型号',trigger: 'blur'},
+  ],
+  ipAddress: [
+    { required: true,  message:'请输入ip地址',trigger: 'blur'},
+    { pattern:/^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/,message: '请输入正确的ip地址',trigger: 'blur'}
+  ],
+  gatewayId: [
+    { required: true,  message:'请选择网关',trigger: 'blur'},
+  ]
+})
+
+const getNowDay = ()=>{
+  let timestamp = Date.now(); // 获取当前时间戳,单位是毫秒
+  cameraInfo.value.installTime = new Date(timestamp)
+}
+
+const getRandomCode = (prex)=>{
+  let str1 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+  let arr1 = str1.split("");
+  cameraInfo.value.cameraCode = prex
+  for(let i = 0; i < 10;i++){
+    let n = Math.round(Math.random()*(arr1.length -1));
+    cameraInfo.value.cameraCode += arr1[n]
+  }
+}
+
+const tableRowClassName = ({row, rowIndex})=>{
+  if ((rowIndex+1) % 2  === 0) {
+    return 'success-row';
+  }
+  return '';
+}
+const getTableData = async() => {
+  const table = await getCameraList({page: page.value, pageSize: pageSize.value,...searchInfo.value})
+  if (table.code === 0) {
+    tableData.value = table.data.list
+    total.value = table.data.total
+    page.value = table.data.page
+    pageSize.value = table.data.pageSize
+  }
+}
+const getCameraParms = async() => {
+  const table = await getPublicGateway()
+  if (table.code === 0) {
+    gatewayList.value = table.data.pubGateway
+  }
+}
+
+getCameraParms()
+getTableData()
+
+const view = (row)=>{
+  viewCameraDialog.value = true
+  cameraInfo.value = JSON.parse(JSON.stringify(row))
+  cameraInfo.value.installTime = new Date(cameraInfo.value.installTime).toLocaleDateString()
+}
+
+
+
+const handleSizeChange = (val) => {
+  pageSize.value = val
+  getTableData()
+}
+
+const handleCurrentChange = (val) => {
+  page.value = val
+  getTableData()
+}
+
+const add = () => {
+  cameraInfo.value={GateWay:{},shunt:1,cameraType:0}
+  dialogFlag.value = 'add'
+  addCameraDialog.value = true
+  getNowDay()
+  getRandomCode("SXT-")
+}
+
+const closeAddCameraDialog = () => {
+  cameraForm.value.resetFields()
+  addCameraDialog.value = false
+  isFlag.value=''
+}
+
+// 弹窗相关
+const onSubmit = () => {
+  page.value = 1
+  pageSize.value = 10
+  getTableData()
+}
+const onReset = () => {
+  searchInfo.value = {}
+}
+
+const enterAddCameraDialog = async() => {
+  cameraForm.value.validate(async valid => {
+    if (valid) {
+      const req = {
+        ...cameraInfo.value
+      }
+      if (dialogFlag.value === 'add') {
+        const res = await addCamera(req)
+        if (res.code === 0) {
+          ElMessage({ type: 'success', message: '创建成功' })
+          await getTableData()
+          closeAddCameraDialog()
+        }
+      }
+      if (dialogFlag.value === 'edit') {
+        const res = await setCameraInfo(req)
+        if (res.code === 0) {
+          ElMessage({ type: 'success', message: '编辑成功' })
+          await getTableData()
+          closeAddCameraDialog()
+        }
+      }
+    }
+  })
+}
+
+const editCamera = (row) => {
+  dialogFlag.value = 'edit'
+  cameraInfo.value = JSON.parse(JSON.stringify(row))
+  addCameraDialog.value = true
+}
+const deleteCamera = (obj) => {
+  ElMessageBox.confirm('您确定要删除吗?', '提示', {
+    confirmButtonText: '确定',
+    cancelButtonText: '取消',
+    type: 'warning',
+  })
+      .then(async() => {
+        const res = await deleteBaseCamera({ ID:obj.ID })
+        if (res.code === 0) {
+          ElMessage({
+            type: 'success',
+            message: '删除成功!',
+          })
+          getTableData()
+        }
+      })
+      .catch(() => {
+        ElMessage({
+          type: 'info',
+          message: '已取消删除',
+        })
+      })
+}
+
+</script>
+<style>
+.el-table .success-row {
+  background: #f3fdef;
+}
+
+.onlinebox{
+  width: 12px; height: 12px;border-radius: 50%; display: inline-block; margin-right: 4px; position: relative; top: 1px;
+}
+
+.el-dialog__header{
+  border-bottom: 1px solid #e8eaec;
+}
+.el-dialog__footer {
+  border-top: 1px solid #e8eaec;
+}
+</style>

+ 472 - 0
web/src/view/devicesAdmin/gateway/gateway.vue

@@ -0,0 +1,472 @@
+<template>
+  <div>
+    <div class="gva-search-box">
+      <el-form
+          ref="searchForm"
+          :inline="true"
+          :model="searchInfo"
+      >
+        <el-form-item label="名称或编码">
+          <el-input
+              v-model="searchInfo.keyword"
+              placeholder="搜索名称或编码"
+          />
+        </el-form-item>
+        <el-form-item>
+          <el-button
+              type="primary"
+              icon="search"
+              @click="onSubmit"
+          >查询</el-button>
+          <el-button
+              icon="refresh"
+              @click="onReset"
+          >重置</el-button>
+        </el-form-item>
+      </el-form>
+    </div>
+    <div class="gva-table-box">
+      <div class="gva-btn-list">
+        <el-button
+            type="primary"
+            icon="plus"
+            @click="add()"
+        >新增</el-button>
+      </div>
+      <el-table
+          :data="tableData"
+          style="width: 100%; margin-bottom: 20px"
+          row-key="id"
+          border
+          :table-layout="'fixed'"
+          :row-class-name="tableRowClassName"
+      >
+        <el-table-column prop="gateway.id" label="#" :width="80"/>
+        <el-table-column prop="gateway.gatewayName" label="网关名称" />
+        <el-table-column prop="gateway.gatewayCode" label="编码">
+          <template #default="scope">
+            <el-tag effect="light">{{ scope.row.gateway.gatewayCode }}</el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column prop="gateway.gatewayBrand" label="品牌" />
+        <el-table-column prop="gateway.gatewayModel" label="型号"/>
+        <el-table-column prop="gateway.gatewayAddress" label="所在地址"/>
+        <el-table-column prop="gateway.status" label="在线状态">
+          <template #default="scope">
+            <div class="onlinebox" :style="{'background': scope.row.gateway.status===1 ? 'red':'green' }"></div>
+            <span :style="{ color: scope.row.gateway.status === 1 ? 'red' : 'green' }">{{ scope.row.gateway.status === 1 ? '离线' : '在线' }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column
+            align="left"
+            fixed="right"
+            label="操作"
+            :width="300"
+        >
+          <template #default="scope">
+            <el-button
+                type="primary"
+                link
+                icon="view"
+                @click="view(scope.row)"
+            >查看</el-button>
+            <el-button
+                type="primary"
+                link
+                icon="edit"
+                @click="editGateway(scope.row)"
+            >编辑</el-button>
+            <el-button
+                type="primary"
+                link
+                icon="delete"
+                @click="deleteGateway(scope.row)"
+            >删除</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+      <div class="gva-pagination">
+        <el-pagination
+            :current-page="page"
+            :page-size="pageSize"
+            :page-sizes="[10, 30, 50, 100]"
+            :total="total"
+            layout="total, sizes, prev, pager, next, jumper"
+            @current-change="handleCurrentChange"
+            @size-change="handleSizeChange"
+        />
+      </div>
+
+      <el-dialog v-model="addGatewayDialog" title="智慧网关" width="900">
+        <el-form
+            ref="gatewayForm"
+            :rules="rules"
+            :model="gatewayInfo"
+            label-width="100px"
+            style="padding: 15px"
+        >
+          <el-row>
+            <el-col :span="12">
+              <el-form-item label="网关名称:" :inline="false" prop="gateway.gatewayName">
+                <el-input v-model="gatewayInfo.gateway.gatewayName"></el-input>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="编码:" :inline="false">
+                <el-input disabled v-model="gatewayInfo.gateway.gatewayCode"></el-input>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row>
+            <el-col :span="12">
+              <el-form-item label="品牌:" :inline="false" prop="gateway.gatewayBrand">
+                <el-input v-model="gatewayInfo.gateway.gatewayBrand"></el-input>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="型号:" :inline="false" prop="gateway.gatewayModel">
+                <el-input v-model="gatewayInfo.gateway.gatewayModel"></el-input>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row>
+            <el-col :span="12">
+              <el-form-item label="ip地址:" :inline="false" prop="gateway.ipAddress">
+                <el-input v-model="gatewayInfo.gateway.ipAddress"></el-input>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="所在地址:" :inline="false">
+                <el-input v-model="gatewayInfo.gateway.gatewayAddress"></el-input>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row>
+            <el-col :span="12">
+              <el-form-item label="安装时间:" :inline="false">
+                <el-date-picker
+                    v-model="gatewayInfo.gateway.installTime"
+                    type="date"
+                    placeholder="Pick a day"
+                    size="default"
+                />
+              </el-form-item>
+            </el-col>
+          </el-row>
+        </el-form>
+        <template #footer>
+          <div class="dialog-footer">
+            <el-button @click="closeAddGatewayDialog">取消</el-button>
+            <el-button type="primary" @click="enterAddGatewayDialog">
+              确定
+            </el-button>
+          </div>
+        </template>
+      </el-dialog>
+
+      <el-dialog v-model="viewGatewayDialog" title="详情" style="padding: 35px">
+        <el-form
+            :model="gatewayInfo"
+            label-width="100px"
+            style="padding: 20px"
+        >
+          <el-row>
+            <el-col :span="12">
+              <el-form-item label="网关名称:" :inline="false">
+                {{gatewayInfo.gateway.gatewayName }}
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="编码:" :inline="false">
+                {{gatewayInfo.gateway.gatewayCode }}
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row>
+            <el-col :span="12">
+              <el-form-item label="品牌:" :inline="false">
+                {{gatewayInfo.gateway.gatewayBrand }}
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="型号:" :inline="false">
+                {{gatewayInfo.gateway.gatewayModel }}
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row>
+            <el-col :span="12">
+              <el-form-item label="ip地址:" :inline="false">
+                {{gatewayInfo.gateway.ipAddress }}
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="所在地址:" :inline="false">
+                {{gatewayInfo.gateway.gatewayAddress }}
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row>
+            <el-col :span="12">
+              <el-form-item label="安装时间:" :inline="false">
+                {{gatewayInfo.gateway.installTime }}
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="在线状态:" :inline="false">
+                <div class="onlinebox" :style="{'background': gatewayInfo.gateway.status===1 ? 'red':'green' }"></div>
+                <span :style="{ color: gatewayInfo.gateway.status === 1 ? 'red' : 'green' }">{{ gatewayInfo.gateway.status === 1 ? '离线' : '在线' }}</span>
+              </el-form-item>
+            </el-col>
+          </el-row>
+        </el-form>
+        <div style="padding: 20px 0px;font-weight: bolder; border-top: solid 1px #e8eaec">关联设备:</div>
+        <el-tabs type="border-card" v-model="activeName">
+          <el-tab-pane :label="'摄像机【'+cameracount+'】'" name="camera">
+            <el-table :data="gatewayInfo.relationDev.cameraList" style="width: 100%" >
+              <el-table-column fixed prop="shunt" label="所属分路" width="80px">
+                <template #default="scope">
+                  {{ scope.row.shunt==1?'主路':'支路' }}
+                </template>
+              </el-table-column>
+              <el-table-column prop="cameraName" label="名称" width="150px"/>
+              <el-table-column prop="cameraBrand" label="品牌" width="100px"/>
+              <el-table-column prop="cameraModel" label="型号" width="250px"/>
+              <el-table-column prop="ipAddress" label="ip地址" width="150px"/>
+              <el-table-column prop="shuntDescribe" label="分路描述" width="200px"/>
+              <el-table-column prop="status" fixed="right" label="状态" width="80px">
+                <template #default="scope">
+                  <div class="onlinebox" :style="{'background': scope.row.status===1 ? 'red':'green' }"></div>
+                  <span :style="{ color: scope.row.status === 1 ? 'red' : 'green' }">{{ scope.row.status === 1 ? '离线' : '在线' }}</span>
+                </template>
+              </el-table-column>
+            </el-table>
+          </el-tab-pane>
+          <el-tab-pane :label="'LED信息屏【'+screenscount+'】'" name="screens">
+            <el-table :data="gatewayInfo.relationDev.screensList" style="width: 100%" :table-layout="'fixed'">
+              <el-table-column fixed prop="shunt" label="所属分路" width="80px">
+                <template #default="scope">
+                  {{ scope.row.shunt==1?'主路':'支路' }}
+                </template>
+              </el-table-column>
+              <el-table-column prop="screensName" label="名称" width="150px"/>
+              <el-table-column prop="screensBrand" label="品牌" width="100px"/>
+              <el-table-column prop="screensModel" label="型号" width="250px"/>
+              <el-table-column prop="ipAddress" label="ip地址" width="150px"/>
+              <el-table-column prop="shuntDescribe" label="分路描述" width="200px"/>
+              <el-table-column prop="status" fixed="right" label="状态" width="80px">
+                <template #default="scope">
+                  <div class="onlinebox" :style="{'background': scope.row.status===1 ? 'red':'green' }"></div>
+                  <span :style="{ color: scope.row.status === 1 ? 'red' : 'green' }">{{ scope.row.status === 1 ? '离线' : '在线' }}</span>
+                </template>
+              </el-table-column>
+            </el-table>
+          </el-tab-pane>
+          <el-tab-pane :label="'雷达【'+radarcount+'】'" name="radar">
+            radar
+          </el-tab-pane>
+        </el-tabs>
+      </el-dialog>
+    </div>
+  </div>
+</template>
+<script setup>
+import {addGateway, deleteBaseGateway, getGatewayList, setGatewayInfo} from "@/api/gateway";
+import {ref} from 'vue'
+import {ElMessage, ElMessageBox} from "element-plus";
+
+const page = ref(1)
+const total = ref(0)
+const pageSize = ref(10)
+const tableData = ref([])
+const searchInfo = ref({})
+const gatewayInfo = ref({
+  gateway:{}
+})
+
+const gatewayForm = ref(null)
+const dialogFlag = ref('add')
+const isFlag = ref('')
+const addGatewayDialog = ref(false)
+const viewGatewayDialog = ref(false)
+const rules = ref({
+  "gateway.gatewayName": [
+    { required: true, message: '请输入网关名称',trigger: 'blur'},
+    { min: 5, message: '最低5位字符', trigger: 'blur' }
+  ],
+  "gateway.gatewayBrand": [
+    { required: true, message: '请填写品牌',trigger: 'blur'},
+  ],
+    "gateway.gatewayModel": [
+    { required: true, message: '请填写型号',trigger: 'blur'},
+  ],
+    "gateway.ipAddress": [
+    { required: true,  message:'请输入ip地址',trigger: 'blur'},
+    { pattern:/^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/,message: '请输入正确的ip地址',trigger: 'blur'}
+  ]
+})
+
+const getNowDay = ()=>{
+  let timestamp = Date.now(); // 获取当前时间戳,单位是毫秒
+  gatewayInfo.value.gateway.installTime = new Date(timestamp)
+}
+
+const getRandomCode = (prex)=>{
+  let str1 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+  let arr1 = str1.split("");
+  gatewayInfo.value.gateway.gatewayCode = prex
+  for(let i = 0; i < 10;i++){
+    let n = Math.round(Math.random()*(arr1.length -1));
+    gatewayInfo.value.gateway.gatewayCode += arr1[n]
+  }
+}
+
+const tableRowClassName = ({row, rowIndex})=>{
+  if ((rowIndex+1) % 2  === 0) {
+    return 'success-row';
+  }
+  return '';
+}
+const getTableData = async() => {
+  const table = await getGatewayList({page: page.value, pageSize: pageSize.value,...searchInfo.value})
+  if (table.code === 0) {
+    tableData.value = table.data.list
+    total.value = table.data.total
+    page.value = table.data.page
+    pageSize.value = table.data.pageSize
+  }
+}
+getTableData()
+
+const handleSizeChange = (val) => {
+  pageSize.value = val
+  getTableData()
+}
+
+const handleCurrentChange = (val) => {
+  page.value = val
+  getTableData()
+}
+
+// 标签页的一些声明
+const activeName = ref('camera')
+const cameracount = ref(0)
+const screenscount = ref(0)
+const radarcount = ref(0)
+const add = () => {
+  gatewayInfo.value={gateway:{},relationDev:{}}
+  dialogFlag.value = 'add'
+  addGatewayDialog.value = true
+  getNowDay()
+  getRandomCode("ZHWG-")
+}
+
+const closeAddGatewayDialog = () => {
+  gatewayForm.value.resetFields()
+  addGatewayDialog.value = false
+  isFlag.value=''
+}
+
+// 弹窗相关
+const onSubmit = () => {
+  page.value = 1
+  pageSize.value = 10
+  getTableData()
+}
+const onReset = () => {
+  searchInfo.value = {}
+}
+
+const view = (row)=>{
+  activeName.value = 'camera'
+  viewGatewayDialog.value = true
+  gatewayInfo.value = JSON.parse(JSON.stringify(row))
+  gatewayInfo.value.gateway.installTime = new Date(gatewayInfo.value.gateway.installTime).toLocaleDateString()
+  cameracount.value=gatewayInfo.value.relationDev.cameraList.length
+  screenscount.value=gatewayInfo.value.relationDev.screensList.length
+}
+
+const enterAddGatewayDialog = async() => {
+  gatewayForm.value.validate(async valid => {
+    if (valid) {
+      const req = {
+        ...gatewayInfo.value.gateway
+      }
+      if (dialogFlag.value === 'add') {
+        const res = await addGateway(req)
+        if (res.code === 0) {
+          ElMessage({ type: 'success', message: '创建成功' })
+          await getTableData()
+          closeAddGatewayDialog()
+        }
+      }
+      if (dialogFlag.value === 'edit') {
+        const res = await setGatewayInfo(req)
+        if (res.code === 0) {
+          ElMessage({ type: 'success', message: '编辑成功' })
+          await getTableData()
+          closeAddGatewayDialog()
+        }
+      }
+    }
+  })
+}
+
+const editGateway = (row) => {
+  dialogFlag.value = 'edit'
+  gatewayInfo.value = JSON.parse(JSON.stringify(row))
+  addGatewayDialog.value = true
+}
+const deleteGateway = (obj) => {
+  for (let prop in obj.relationDev) {
+    if (Array.isArray(obj.relationDev[prop])) {
+      if (obj.relationDev[prop].length !== 0) {
+        ElMessage({
+          type: 'warning',
+          message: '请先删除关联的设备',
+        })
+        return
+        break;
+      }
+    }
+  }
+  ElMessageBox.confirm('您确定要删除吗?', '提示', {
+    confirmButtonText: '确定',
+    cancelButtonText: '取消',
+    type: 'warning',
+  })
+      .then(async() => {
+        const res = await deleteBaseGateway({ ID:obj.gateway.id })
+        if (res.code === 0) {
+          ElMessage({
+            type: 'success',
+            message: '删除成功!',
+          })
+          getTableData()
+        }
+      })
+      .catch(() => {
+        ElMessage({
+          type: 'info',
+          message: '已取消删除',
+        })
+      })
+}
+
+</script>
+<style>
+.el-table .success-row {
+  background: #f3fdef;
+}
+
+.onlinebox{
+  width: 12px; height: 12px;border-radius: 50%; display: inline-block; margin-right: 4px; position: relative; top: 1px;
+}
+
+.el-dialog__header{
+  border-bottom: 1px solid #e8eaec;
+}
+.el-dialog__footer {
+  border-top: 1px solid #e8eaec;
+}
+</style>

+ 23 - 0
web/src/view/devicesAdmin/index.vue

@@ -0,0 +1,23 @@
+<template>
+  <div>
+    <router-view v-slot="{ Component }">
+      <transition
+        mode="out-in"
+        name="el-fade-in-linear"
+      >
+        <keep-alive :include="routerStore.keepAliveRouters">
+          <component :is="Component" />
+        </keep-alive>
+      </transition>
+    </router-view>
+  </div>
+</template>
+
+<script setup>
+import { useRouterStore } from '@/pinia/modules/router'
+const routerStore = useRouterStore()
+
+defineOptions({
+  name: 'DevicesAdmin'
+})
+</script>

+ 493 - 0
web/src/view/devicesAdmin/screens/screens.vue

@@ -0,0 +1,493 @@
+<template>
+  <div>
+    <div class="gva-search-box">
+      <el-form
+          ref="searchForm"
+          :inline="true"
+          :model="searchInfo"
+      >
+        <el-form-item label="名称或编码">
+          <el-input
+              v-model="searchInfo.keyword"
+              placeholder="搜索名称或编码"
+          />
+        </el-form-item>
+        <el-form-item label="所属分路">
+          <el-select v-model="searchInfo.shunt" placeholder="所属分路">
+            <el-option label="主路" value=1></el-option>
+            <el-option label="支路" value=2></el-option>
+          </el-select>
+        </el-form-item>
+
+        <el-form-item>
+          <el-button
+              type="primary"
+              icon="search"
+              @click="onSubmit"
+          >查询</el-button>
+          <el-button
+              icon="refresh"
+              @click="onReset"
+          >重置</el-button>
+        </el-form-item>
+      </el-form>
+    </div>
+    <div class="gva-table-box">
+      <div class="gva-btn-list">
+        <el-button
+            type="primary"
+            icon="plus"
+            @click="add()"
+        >新增</el-button>
+      </div>
+      <el-table
+          :data="tableData"
+          style="width: 100%; margin-bottom: 20px"
+          row-key="id"
+          border
+          :table-layout="'fixed'"
+          :row-class-name="tableRowClassName"
+      >
+        <el-table-column prop="ID" label="#" :width="80"/>
+        <el-table-column prop="shunt" label="所属分路" :width="100">
+          <template #default="scope">
+            {{ scope.row.shunt===1?"主路":scope.row.shunt===2?"支路":"未知" }}
+          </template>
+        </el-table-column>
+        <el-table-column prop="screensName" label="名称" />
+        <el-table-column prop="screensCode" label="编码">
+          <template #default="scope">
+            <el-tag effect="light">{{ scope.row.screensCode }}</el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column prop="screensBrand" label="品牌" />
+        <el-table-column prop="screensModel" label="型号"/>
+        <el-table-column prop="GateWay.gatewayName" label="所属网关"/>
+        <el-table-column prop="status" label="在线状态">
+          <template #default="scope">
+            <div class="onlinebox" :style="{'background': scope.row.status===1 ? 'red':'green' }"></div>
+            <span :style="{ color: scope.row.status === 1 ? 'red' : 'green' }">{{ scope.row.status === 1 ? '离线' : '在线' }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column
+            align="left"
+            fixed="right"
+            label="操作"
+            :width="300"
+        >
+          <template #default="scope">
+            <el-button
+                type="primary"
+                link
+                icon="view"
+                @click="view(scope.row)"
+            >查看</el-button>
+            <el-button
+                type="primary"
+                link
+                icon="edit"
+                @click="editScreens(scope.row)"
+            >编辑</el-button>
+            <el-button
+                type="primary"
+                link
+                icon="delete"
+                @click="deleteScreens(scope.row)"
+            >删除</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+      <div class="gva-pagination">
+        <el-pagination
+            :current-page="page"
+            :page-size="pageSize"
+            :page-sizes="[10, 30, 50, 100]"
+            :total="total"
+            layout="total, sizes, prev, pager, next, jumper"
+            @current-change="handleCurrentChange"
+            @size-change="handleSizeChange"
+        />
+      </div>
+
+      <el-dialog v-model="addScreensDialog" title="LED显示屏" width="900">
+        <el-form
+            ref="screensForm"
+            :rules="rules"
+            :model="screensInfo"
+            label-width="100px"
+            style="padding: 15px"
+        >
+          <el-row>
+            <el-col :span="12">
+              <el-form-item label="屏幕名称:" :inline="false" prop="screensName">
+                <el-input v-model="screensInfo.screensName"></el-input>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="编码:" :inline="false">
+                <el-input disabled v-model="screensInfo.screensCode"></el-input>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row>
+            <el-col :span="12">
+              <el-form-item label="品牌:" :inline="false" prop="screensBrand">
+                <el-input v-model="screensInfo.screensBrand"></el-input>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="型号:" :inline="false" prop="screensModel">
+                <el-input v-model="screensInfo.screensModel"></el-input>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row>
+            <el-col :span="12">
+              <el-form-item label="ip地址:" :inline="false" prop="ipAddress">
+                <el-input v-model="screensInfo.ipAddress"></el-input>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="所属网关:" :inline="false" prop="gatewayId">
+                <el-select v-model="screensInfo.gatewayId" placeholder="所属网关">
+                  <el-option v-for=" (item) in screensParams.gatewayList" :label="item.gatewayName" :value="item.id"></el-option>
+                </el-select>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row>
+            <el-col :span="12">
+              <el-form-item label="分辨率:" :inline="false">
+                <el-select v-model="screensInfo.resolutionId" placeholder="请选择分辨率">
+                  <el-option v-for=" (item) in screensParams.resolution" :label="item.price" :value="item.ID"></el-option>
+                </el-select>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="屏幕尺寸:" :inline="false">
+                <el-select v-model="screensInfo.screensSizeId" placeholder="请选择屏幕尺寸">
+                  <el-option v-for=" (item) in screensParams.screensSize" :label="item.size" :value="item.ID"></el-option>
+                </el-select>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row>
+            <el-col :span="12">
+              <el-form-item label="所属分路:" :inline="false">
+                <el-select v-model="screensInfo.shunt" placeholder="请选择所属分路">
+                  <el-option label="主路" :value=1></el-option>
+                  <el-option label="支路" :value=2></el-option>
+                </el-select>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="分路描述:" :inline="false">
+                <el-input v-model="screensInfo.shuntDescribe"></el-input>
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row>
+            <el-col :span="12">
+              <el-form-item label="安装时间:" :inline="false">
+                <el-date-picker
+                    v-model="screensInfo.installTime"
+                    type="date"
+                    placeholder="Pick a day"
+                    size="default"
+                />
+              </el-form-item>
+            </el-col>
+          </el-row>
+        </el-form>
+        <template #footer>
+          <div class="dialog-footer">
+            <el-button @click="closeAddScreensDialog">取消</el-button>
+            <el-button type="primary" @click="enterAddScreensDialog">
+              确定
+            </el-button>
+          </div>
+        </template>
+      </el-dialog>
+
+      <el-dialog v-model="viewScreensDialog" title="详情" style="padding: 35px">
+        <el-form
+            :model="screensInfo"
+            label-width="100px"
+            style="padding: 20px"
+        >
+          <el-row>
+            <el-col :span="12">
+              <el-form-item label="屏幕名称:" :inline="false">
+                {{screensInfo.screensName }}
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="编码:" :inline="false">
+                {{screensInfo.screensCode }}
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row>
+            <el-col :span="12">
+              <el-form-item label="品牌:" :inline="false">
+                {{screensInfo.screensBrand }}
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="型号:" :inline="false">
+                {{screensInfo.screensModel }}
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row>
+            <el-col :span="12">
+              <el-form-item label="ip地址:" :inline="false">
+                {{screensInfo.ipAddress }}
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="所属网关:" :inline="false">
+                {{screensInfo.GateWay.gatewayName }}
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row>
+            <el-col :span="12">
+              <el-form-item label="分辨率:" :inline="false">
+                {{screensInfo.Resolution.price }}
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="屏幕尺寸:" :inline="false">
+                {{screensInfo.ScreensSize.size }}
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row>
+            <el-col :span="12">
+              <el-form-item label="所属分路:" :inline="false">
+                <el-tag effect="dark">{{screensInfo.shunt===1?"主路":screensInfo.shunt===2?"支路":"未知"}}</el-tag>
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="分路描述:" :inline="false">
+                {{screensInfo.shuntDescribe }}
+              </el-form-item>
+            </el-col>
+          </el-row>
+          <el-row>
+            <el-col :span="12">
+              <el-form-item label="安装时间:" :inline="false">
+                {{screensInfo.installTime }}
+              </el-form-item>
+            </el-col>
+            <el-col :span="12">
+              <el-form-item label="在线状态:" :inline="false">
+                <div class="onlinebox" :style="{'background': screensInfo.status===1 ? 'red':'green' }"></div>
+                <span :style="{ color: screensInfo.status === 1 ? 'red' : 'green' }">{{ screensInfo.status === 1 ? '离线' : '在线' }}</span>
+              </el-form-item>
+            </el-col>
+          </el-row>
+        </el-form>
+      </el-dialog>
+    </div>
+  </div>
+</template>
+<script setup>
+import {deleteBaseScreens, getScreensList, queryscreensParms,setScreensInfo,addScreens} from "@/api/screens";
+import { ref,reactive,nextTick} from 'vue'
+import {ElMessage, ElMessageBox} from "element-plus";
+const page = ref(1)
+const total = ref(0)
+const pageSize = ref(10)
+const tableData = ref([])
+const searchInfo = ref({})
+const screensInfo = ref({})
+const screensParams = reactive({
+  resolution:[],
+  screensSize:[],
+  gatewayList:[]
+})
+const screensForm = ref(null)
+const dialogFlag = ref('add')
+const isFlag = ref('')
+const addScreensDialog = ref(false)
+const viewScreensDialog = ref(false)
+
+const rules = ref({
+  screensName: [
+    { required: true, message: '请输入名称',trigger: 'blur'},
+    { min: 5, message: '最低5位字符', trigger: 'blur' }
+  ],
+  screensBrand: [
+    { required: true, message: '请填写品牌',trigger: 'blur'},
+  ],
+  screensModel: [
+    { required: true, message: '请填写型号',trigger: 'blur'},
+  ],
+  ipAddress: [
+    { required: true,  message:'请输入ip地址',trigger: 'blur'},
+    { pattern:/^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/,message: '请输入正确的ip地址',trigger: 'blur'}
+  ],
+  gatewayId: [
+    { required: true,  message:'请选择网关',trigger: 'blur'},
+  ]
+})
+
+const getNowDay = ()=>{
+  let timestamp = Date.now(); // 获取当前时间戳,单位是毫秒
+  screensInfo.value.installTime = new Date(timestamp)
+}
+
+const getRandomCode = (prex)=>{
+  let str1 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+  let arr1 = str1.split("");
+  screensInfo.value.screensCode = prex
+  for(let i = 0; i < 10;i++){
+    let n = Math.round(Math.random()*(arr1.length -1));
+    screensInfo.value.screensCode += arr1[n]
+  }
+}
+
+const tableRowClassName = ({row, rowIndex})=>{
+  if ((rowIndex+1) % 2  === 0) {
+    return 'success-row';
+  }
+  return '';
+}
+const getTableData = async() => {
+  const table = await getScreensList({page: page.value, pageSize: pageSize.value,...searchInfo.value})
+  if (table.code === 0) {
+    tableData.value = table.data.list
+    total.value = table.data.total
+    page.value = table.data.page
+    pageSize.value = table.data.pageSize
+  }
+}
+const getScreensParms = async() => {
+  const table = await queryscreensParms()
+  if (table.code === 0) {
+    screensParams.screensSize = table.data.screensSize
+    screensParams.resolution = table.data.resolution
+    screensParams.gatewayList = table.data.pubGateway
+  }
+}
+
+getScreensParms()
+getTableData()
+
+const view = (row)=>{
+  viewScreensDialog.value = true
+  screensInfo.value = JSON.parse(JSON.stringify(row))
+  screensInfo.value.installTime = new Date(screensInfo.value.installTime).toLocaleDateString()
+}
+
+
+
+const handleSizeChange = (val) => {
+  pageSize.value = val
+  getTableData()
+}
+
+const handleCurrentChange = (val) => {
+  page.value = val
+  getTableData()
+}
+
+const add = () => {
+  screensInfo.value={GateWay:{},Resolution:{},ScreensSize:{},resolutionId:1,screensSizeId:1,shunt:1}
+  dialogFlag.value = 'add'
+  addScreensDialog.value = true
+  getNowDay()
+  getRandomCode("XSP-")
+}
+
+const closeAddScreensDialog = () => {
+  screensForm.value.resetFields()
+  addScreensDialog.value = false
+  isFlag.value=''
+}
+
+// 弹窗相关
+const onSubmit = () => {
+  page.value = 1
+  pageSize.value = 10
+  getTableData()
+}
+const onReset = () => {
+  searchInfo.value = {}
+}
+
+const enterAddScreensDialog = async() => {
+  screensForm.value.validate(async valid => {
+    if (valid) {
+      const req = {
+        ...screensInfo.value
+      }
+      if (dialogFlag.value === 'add') {
+        const res = await addScreens(req)
+        if (res.code === 0) {
+          ElMessage({ type: 'success', message: '创建成功' })
+          await getTableData()
+          closeAddScreensDialog()
+        }
+      }
+      if (dialogFlag.value === 'edit') {
+        const res = await setScreensInfo(req)
+        if (res.code === 0) {
+          ElMessage({ type: 'success', message: '编辑成功' })
+          await getTableData()
+          closeAddScreensDialog()
+        }
+      }
+    }
+  })
+}
+
+const editScreens = (row) => {
+  dialogFlag.value = 'edit'
+  screensInfo.value = JSON.parse(JSON.stringify(row))
+  addScreensDialog.value = true
+}
+const deleteScreens = (obj) => {
+  ElMessageBox.confirm('您确定要删除吗?', '提示', {
+    confirmButtonText: '确定',
+    cancelButtonText: '取消',
+    type: 'warning',
+  })
+      .then(async() => {
+        console.log(obj)
+        const res = await deleteBaseScreens({ ID:obj.ID })
+        if (res.code === 0) {
+          ElMessage({
+            type: 'success',
+            message: '删除成功!',
+          })
+          getTableData()
+        }
+      })
+      .catch(() => {
+        ElMessage({
+          type: 'info',
+          message: '已取消删除',
+        })
+      })
+}
+
+</script>
+<style>
+.el-table .success-row {
+  background: #f3fdef;
+}
+
+.onlinebox{
+  width: 12px; height: 12px;border-radius: 50%; display: inline-block; margin-right: 4px; position: relative; top: 1px;
+}
+
+.el-dialog__header{
+  border-bottom: 1px solid #e8eaec;
+}
+.el-dialog__footer {
+  border-top: 1px solid #e8eaec;
+}
+</style>