package controllers import ( "basic.com/pubsub/protomsg.git" "basic.com/valib/bhomeclient.git" "basic.com/valib/logger.git" "encoding/json" "github.com/satori/go.uuid" "image" "os" "path" "strconv" "strings" "vamicro/extend/util" "vamicro/scene-service/models" "vamicro/scene-service/service" "vamicro/scene-service/vo" ) type CameraPolygonController struct { } // @Summary 根据cameraId查询摄像机多边形 // @Description 根据cameraId查询摄像机多边形 // @Accept json // @Produce json // @Tags 摄像机多边形 // @Param cameraId query string true "摄像机id" // @Success 200 {string} json "{"code":200, success:true, msg:"", data:""}" // @Failure 500 {string} json "{"code":500, success:false, msg:"", data:""}" // @Router /data/api-v/polygon/findByCameraId [get] func (cpc CameraPolygonController) FindByCameraId(h *bhomeclient.WrapperHandler, c *bhomeclient.Request) *bhomeclient.Reply { cameraId := c.Query("cameraId") if cameraId == "" { return &bhomeclient.Reply{Success: false, Msg: "参数有误"} } sv := service.NewCameraPolygonService(h.Bk) voInfo := sv.FindByCameraId(cameraId) return &bhomeclient.Reply{Success: true, Data: voInfo} } type CPN struct { models.CameraPolygon CameraName string `json:"camera_name"` } // @Summary 查找所有多边形,返回的是数据库的结构 // @Description 查找所有多边形,返回的是数据库的结构 // @Produce json // @Tags 摄像机多边形 // @Success 200 {string} json "{"code":200, success:true, msg:"", data:""}" // @Failure 500 {string} json "{"code":500, success:false, msg:"", data:""}" // @Router /data/api-v/polygon/findAll [get] func (cpc CameraPolygonController) FindAll(h *bhomeclient.WrapperHandler, c *bhomeclient.Request) *bhomeclient.Reply { m := make(map[string]string) idNameM := service.GetAllCamIdNameMap() var model models.CameraPolygon polygons := model.FindAll() var result []CPN var arr []CPN //全部区域 for _, p := range polygons { if nn, exist := idNameM[p.CameraId]; exist { me := models.CameraPolygon{ Id: p.CameraId, CameraId: p.CameraId, Name: models.CAMERAPOLYGON_AREA_ALL, Polygon: "", DirectionLine: "", Type: models.TYPE_POLYGON, DefenceState: 1, } cpn := CPN{} cpn.CameraPolygon = me cpn.CameraName = nn if _, ok := m[p.CameraId]; !ok { arr = append(arr, cpn) } m[p.CameraId] = p.CameraId } cpR := CPN{} cpR.CameraPolygon = p if rName, ex := idNameM[p.CameraId]; ex { cpR.CameraName = rName } result = append(result, cpR) } for k, _ := range idNameM { if _, ok := m[k]; !ok { m[k] = k me := models.CameraPolygon{ Id: k, CameraId: k, Name: models.CAMERAPOLYGON_AREA_ALL, Polygon: "", DirectionLine: "", Type: models.TYPE_POLYGON, DefenceState: 1, } cpn := CPN{} cpn.CameraPolygon = me if nn, exist := idNameM[k]; exist { cpn.CameraName = nn } arr = append(arr, cpn) } } result = append(result, arr...) //每一个摄像机都有一个默认的全部区域 return &bhomeclient.Reply{Success: true, Data: result} } // @Summary 添加或更新摄像机多边形 // @Description 添加或更新摄像机多边形 // @Accept json // @Produce json // @Tags 摄像机多边形 // @Param cameraPolygon body vo.CameraPolygonVo true "摄像机区域结构体,必填" // @Success 200 {string} json "{"code":200, success:true, msg:"", data:""}" // @Failure 500 {string} json "{"code":500, success:false, msg:"", data:""}" // @Router /data/api-v/polygon/save [post] func (cpc CameraPolygonController) Save(h *bhomeclient.WrapperHandler, c *bhomeclient.Request) *bhomeclient.Reply { var cPolygon vo.CameraPolygonVo if err := c.BindJSON(&cPolygon); err != nil { return &bhomeclient.Reply{Success: false, Msg: "参数有误"} } if cPolygon.CameraId == "" { return &bhomeclient.Reply{Success: false, Msg: "摄像机id不能为空"} } sv := service.NewCameraPolygonService(h.Bk) delS, delF := sv.Save(cPolygon) var msg = "" if len(delS) > 0 { msg += "删除成功:" + strings.Join(delS, ",") } if len(delF) > 0 { if msg != "" { msg += ";删除失败:" + strings.Join(delF, ",") } else { msg += "删除失败:" + strings.Join(delF, ",") } } if msg == "" { msg = "保存成功" } logger.Debug("polygon=>Save.msg:", msg) return &bhomeclient.Reply{Success: true, Data: msg} } // @Summary 根据多边形id更新布撤防状态 // @Description 根据多边形id更新布撤防状态 // @Produce json // @Tags 摄像机多边形 // @Param polygonId query string true "多边形id" // @Param defence_state query int true "布撤防状态(0:撤销,1:布防)" // @Success 200 {string} json "{"code":200, success:true, msg:"", data:""}" // @Failure 500 {string} json "{"code":500, success:false, msg:"", data:""}" // @Router /data/api-v/polygon/updateDefenceStateByPolygonId [get] func (cpc CameraPolygonController) UpdateDefenceStateByPolygonId(h *bhomeclient.WrapperHandler, c *bhomeclient.Request) *bhomeclient.Reply { polygonId := c.Query("polygonId") //多边形id defenceState, err := strconv.Atoi(c.Query("defence_state")) //布撤防状态 logger.Debug("polygonId:", polygonId) logger.Debug("defence_state:", defenceState) if err != nil || polygonId == "" || (defenceState != 0 && defenceState != 1) { return &bhomeclient.Reply{Success: false, Msg: "参数有误"} } var model models.CameraPolygon if model.UpdateDefenceStateByPolygonId(polygonId, defenceState) { cpc.addDbChangeMsg(h.Bk, protomsg.TableChanged_T_CameraPolygon, "", protomsg.DbAction_Update, "") return &bhomeclient.Reply{Success: true, Msg: "更新成功"} } else { return &bhomeclient.Reply{Success: false, Msg: "更新失败"} } } // @Summary 根据摄像机id更新布撤防状态 // @Description 根据摄像机id更新布撤防状态 // @Produce json // @Tags 摄像机多边形 // @Param cameraId query string true "摄像机id" // @Param defence_state query int true "布撤防状态(0:撤销,1:布防)" // @Success 200 {string} json "{"code":200, success:true, msg:"", data:""}" // @Failure 500 {string} json "{"code":500, success:false, msg:"", data:""}" // @Router /data/api-v/polygon/updateDefenceStateByCameraId [get] func (cpc CameraPolygonController) UpdateDefenceStateByCameraId(h *bhomeclient.WrapperHandler, c *bhomeclient.Request) *bhomeclient.Reply { cameraId := c.Query("cameraId") //多边形id defenceState, err := strconv.Atoi(c.Query("defence_state")) //布撤防状态 if err != nil || cameraId == "" || (defenceState != 0 && defenceState != 1) { return &bhomeclient.Reply{Success: false, Msg: "参数有误"} } var model models.CameraPolygon if model.UpdateDefenceStateByCameraId(cameraId, defenceState) { cpc.addDbChangeMsg(h.Bk, protomsg.TableChanged_T_CameraPolygon, "", protomsg.DbAction_Update, "") return &bhomeclient.Reply{Success: true, Msg: "更新成功"} } else { return &bhomeclient.Reply{Success: false, Msg: "更新失败"} } } // @Summary 根据摄像机分组id获取分组下的所有区域 // @Description 根据摄像机分组id获取分组下的所有区域 // @Accept json // @Produce json // @Tags 摄像机多边形 // @Param cameraPolygon body vo.CameraPolygonVo true "摄像机区域结构体,必填" // @Success 200 {string} json "{"code":200, success:true, msg:"", data:""}" // @Failure 500 {string} json "{"code":500, success:false, msg:"", data:""}" // @Router /data/api-v/polygon/findByCamGroup [get] func (cpc CameraPolygonController) FindByCamGroup(h *bhomeclient.WrapperHandler, c *bhomeclient.Request) *bhomeclient.Reply { groupId := c.Query("groupId") var cg models.CameraGroup rows, err := cg.SelectById(groupId) if err != nil && rows == 0 { return &bhomeclient.Reply{Msg: "此分组已删除"} } cameraIds := strings.Split(cg.CameraIds, ",") result := make([]vo.CameraPolygonVo, 0) var sv service.CameraPolygonService for _, cid := range cameraIds { result = append(result, sv.FindByCameraId(cid)) } return &bhomeclient.Reply{Success: true, Data: result} } func (cpc CameraPolygonController) addDbChangeMsg(bk bhomeclient.Broker, tChanged protomsg.TableChanged, id string, action protomsg.DbAction, info string) { dbMsg := protomsg.DbChangeMessage{ Table: tChanged, Id: id, Action: action, Info: info, } pb, _ := json.Marshal(dbMsg) bk.Publish(service.ProcName, pb) } // @Summary 获取所有摄像机的区域关联关系 // @Description 获取所有摄像机的区域关联关系 // @Produce json // @Tags 摄像机多边形 // @Success 200 {string} json "{"code":200, success:true, msg:"", data:""}" // @Failure 500 {string} json "{"code":500, success:false, msg:"", data:""}" // @Router /data/api-v/polygon/relation/findAll [get] func (cpc CameraPolygonController) FindAllRelation(h *bhomeclient.WrapperHandler, c *bhomeclient.Request) *bhomeclient.Reply { var cpr models.CameraPolygonRelation arr := cpr.FindAll() if arr == nil { arr = make([]models.CameraPolygonRelation, 0) } return &bhomeclient.Reply{Success: true, Data: arr} } // @Summary 获取两个摄像机的区域关联关系 // @Description 获取两个摄像机的区域关联关系 // @Produce json // @Tags 摄像机多边形 // @Param cameraIds body vo.MultiCamera true "两个摄像机id" // @Success 200 {string} json "{"code":200, success:true, msg:"", data:""}" // @Failure 500 {string} json "{"code":500, success:false, msg:"", data:""}" // @Router /data/api-v/polygon/relations [post] func (cpc CameraPolygonController) Relations(h *bhomeclient.WrapperHandler, c *bhomeclient.Request) *bhomeclient.Reply { var reqBody vo.MultiCamera err := c.BindJSON(&reqBody) if err != nil || len(reqBody.CameraIds) != 2 { return &bhomeclient.Reply{Msg: "参数有误,必须是两个摄像机id"} } var cpr models.CameraPolygonRelation arr, _ := cpr.FindRelations(reqBody.CameraIds[0], reqBody.CameraIds[1]) var list = make([]vo.SaveRelationVo, 0) if arr != nil && len(arr) > 0 { for _, r := range arr { s := vo.SaveRelationVo{ Id: r.Id, SourceCameraId: r.SourceCameraId, SourcePolygonId: r.SourcePolygonId, TargetCameraId: r.TargetCameraId, TargetPolygonId: r.TargetPolygonId, } var sPgnTmp models.CameraPolygon p1, f1 := sPgnTmp.SelectById(r.SourcePolygonId) if f1 && p1.Polygon != "" { location := make([]vo.Point, 0) if err := json.Unmarshal([]byte(p1.Polygon), &location); err == nil { s.SourcePolygon = vo.PolygonS{ Id: p1.Id, Name: p1.Name, Location: location, DefenceState: p1.DefenceState, } } } var tPgnTmp models.CameraPolygon p2, f2 := tPgnTmp.SelectById(r.TargetPolygonId) if f2 && p2.Polygon != "" { location := make([]vo.Point, 0) if err := json.Unmarshal([]byte(p2.Polygon), &location); err == nil { s.TargetPolygon = vo.PolygonS{ Id: p2.Id, Name: p2.Name, Location: location, DefenceState: p2.DefenceState, } } } list = append(list, s) } } return &bhomeclient.Reply{Success: true, Data: list} } func (cpc CameraPolygonController) FindRelationByGroup(h *bhomeclient.WrapperHandler, c *bhomeclient.Request) *bhomeclient.Reply { groupId := c.Query("groupId") if groupId == "" { return &bhomeclient.Reply{Msg: "参数有误"} } var list = make([]vo.SaveRelationVo, 0) var cpr models.CameraPolygonRelation arr, err := cpr.FindByGroupId(groupId) if err == nil && arr != nil { for _, r := range arr { s := vo.SaveRelationVo{ Id: r.Id, SourceCameraId: r.SourceCameraId, SourcePolygonId: r.SourcePolygonId, TargetCameraId: r.TargetCameraId, TargetPolygonId: r.TargetPolygonId, } var sPgnTmp models.CameraPolygon p1, f1 := sPgnTmp.SelectById(r.SourcePolygonId) if f1 && p1.Polygon != "" { location := make([]vo.Point, 0) if err := json.Unmarshal([]byte(p1.Polygon), &location); err == nil { s.SourcePolygon = vo.PolygonS{ Id: p1.Id, Name: p1.Name, Location: location, DefenceState: p1.DefenceState, } } } var tPgnTmp models.CameraPolygon p2, f2 := tPgnTmp.SelectById(r.TargetPolygonId) if f2 && p2.Polygon != "" { location := make([]vo.Point, 0) if err := json.Unmarshal([]byte(p2.Polygon), &location); err == nil { s.TargetPolygon = vo.PolygonS{ Id: p2.Id, Name: p2.Name, Location: location, DefenceState: p2.DefenceState, } } } list = append(list, s) } } return &bhomeclient.Reply{Success: true, Data: list} } // @Summary 获取两个摄像机区域的关联关系 // @Description 获取两个摄像机区域的关联关系 // @Produce json // @Tags 摄像机多边形 // @Param reqBody body vo.SaveRelationVo true "两个摄像机id" // @Success 200 {string} json "{"code":200, success:true, msg:"", data:""}" // @Failure 500 {string} json "{"code":500, success:false, msg:"", data:""}" // @Router /data/api-v/polygon/relation/save [post] func (cpc CameraPolygonController) SaveRelation(h *bhomeclient.WrapperHandler, c *bhomeclient.Request) *bhomeclient.Reply { var reqBody vo.SaveRelationVo err := c.BindJSON(&reqBody) if err != nil { return &bhomeclient.Reply{Msg: "参数有误,参数值不能为空"} } if reqBody.SourceCameraId == reqBody.TargetCameraId { return &bhomeclient.Reply{Msg: "区域关联的摄像机id不能相同"} } logger.Debug("saveRelationVo reqBody:", reqBody) var cpr models.CameraPolygonRelation d, exist := cpr.Exist(reqBody.SourceCameraId, reqBody.SourcePolygonId, reqBody.TargetCameraId, reqBody.TargetPolygonId) if exist { return &bhomeclient.Reply{Msg: "相同关联配置不能重复"} } if reqBody.Id != "" { var tmp = models.CameraPolygonRelation{ Id: reqBody.Id, GroupId: reqBody.GroupId, SourceCameraId: reqBody.SourceCameraId, SourcePolygonId: reqBody.SourcePolygonId, TargetCameraId: reqBody.TargetCameraId, TargetPolygonId: reqBody.TargetPolygonId, } if b, err := tmp.Update(); b { return &bhomeclient.Reply{Success: true, Data: tmp} } else { return &bhomeclient.Reply{Msg: err.Error()} } } else { logger.Debug("saveRelationVo d:", d, "exist:", exist) if !exist { var tmp = models.CameraPolygonRelation{ Id: uuid.NewV4().String(), GroupId: reqBody.GroupId, SourceCameraId: reqBody.SourceCameraId, SourcePolygonId: reqBody.SourcePolygonId, TargetCameraId: reqBody.TargetCameraId, TargetPolygonId: reqBody.TargetPolygonId, } if b, err := tmp.Insert(); b { cpc.addDbChangeMsg(h.Bk, protomsg.TableChanged_T_CameraPolygonRelation, tmp.Id, protomsg.DbAction_Insert, "") return &bhomeclient.Reply{Success: true, Data: tmp} } else { return &bhomeclient.Reply{Msg: err.Error()} } } else { return &bhomeclient.Reply{Success: true, Data: d} } } } // @Summary 删除两个摄像机区域的关联关系 // @Description 删除两个摄像机区域的关联关系 // @Produce json // @Tags 摄像机多边形 // @Param id query string true "关联id" // @Success 200 {string} json "{"code":200, success:true, msg:"", data:""}" // @Failure 500 {string} json "{"code":500, success:false, msg:"", data:""}" // @Router /data/api-v/polygon/relation/del [delete] func (cpc CameraPolygonController) DelRelation(h *bhomeclient.WrapperHandler, c *bhomeclient.Request) *bhomeclient.Reply { id := c.Query("id") if id == "" { return &bhomeclient.Reply{Msg: "参数有误,id不能为空"} } var cpr models.CameraPolygonRelation if cpr.Delete(id) { cpc.addDbChangeMsg(h.Bk, protomsg.TableChanged_T_CameraPolygonRelation, id, protomsg.DbAction_Delete, "") return &bhomeclient.Reply{Success: true, Msg: "删除成功"} } else { return &bhomeclient.Reply{Msg: "删除失败"} } } const panoramaPath = "/opt/vasystem/files/panorama.jpg" // @Summary 获取全景图地址 // @Description 获取全景图地址 // @Produce json // @Tags 全景图 // @Success 200 {string} json "{"code":200, success:true, msg:"", data:""}" // @Failure 500 {string} json "{"code":500, success:false, msg:"", data:""}" // @Router /data/api-v/panorama/show [get] func (cpc CameraPolygonController) ShowPanorama(h *bhomeclient.WrapperHandler, c *bhomeclient.Request) *bhomeclient.Reply { result := make(map[string]interface{}) if util.Exists(panoramaPath) { result["panoramaPath"] = "/files/panorama.jpg" if reader, err := os.Open(panoramaPath); err == nil { defer reader.Close() im, _, err := image.DecodeConfig(reader) if err == nil { result["width"] = im.Width result["height"] = im.Height } } } else { result["panoramaPath"] = "" result["width"] = 0 result["height"] = 0 } return &bhomeclient.Reply{Success: true, Data: result} } // @Summary 上传全景图 // @Description 上传全景图 // @Produce json // @Tags 全景图 // @Success 200 {string} json "{"code":200, success:true, msg:"", data:""}" // @Failure 500 {string} json "{"code":500, success:false, msg:"", data:""}" // @Router /data/api-v/panorama/upload [post] func (cpc CameraPolygonController) UploadPanorama(h *bhomeclient.WrapperHandler, c *bhomeclient.Request) *bhomeclient.Reply { file := c.File if file.Name == "" || file.Bytes == nil || len(file.Bytes) == 0 { logger.Debug("upload panorama file is nil") return &bhomeclient.Reply{Msg: "参数有误"} } ext := path.Ext(file.Name) if ext != ".jpg" { logger.Debug("file.Name:", file.Name) return &bhomeclient.Reply{Msg: "请上传.jpg格式的全景图"} } if util.Exists(panoramaPath) { os.Remove(panoramaPath) } f, err := os.Create(panoramaPath) if err != nil { return &bhomeclient.Reply{Msg: err.Error()} } defer f.Close() n, err := f.Write(file.Bytes) logger.Debug("write panorama file n:", n) if err != nil { return &bhomeclient.Reply{Msg: err.Error()} } return &bhomeclient.Reply{Success: true, Data: map[string]string{ "panoramaPath": "/files/panorama.jpg", }} } // @Summary 获取同步场景数据 // @Description 获取同步场景数据 // @Produce json // @Tags 获取同步场景数据 // @Param reqBody body controllers.CameraGroupVo true "" // @Success 200 {string} json "{"code":200, success:true, msg:"", data:""}" // @Failure 500 {string} json "{"code":500, success:false, msg:"", data:""}" // @Router /data/api-v/camera/group/getSyncSceneData [post] func (cgc *CameraPolygonController) GetSyncSceneData(h *bhomeclient.WrapperHandler, c *bhomeclient.Request) *bhomeclient.Reply { sv := service.NewCameraPolygonService(h.Bk) data := sv.GetSyncSceneData() return &bhomeclient.Reply{Success: true, Msg: "获取成功", Data: data} }