package models import ( "encoding/json" "fmt" "strconv" "strings" "vamicro/camera-common/pub" "vamicro/config" "basic.com/pubsub/protomsg.git" "basic.com/valib/logger.git" ) const ( Default_Layer = -9999 //摄像机添加进来的默认楼层 TYPE_LOCAL_CAMERA = 0 //本地摄像机 TYPE_GB28181_CAMERA = 1 //国标摄像机 TYPE_RUNTYPE_VIDEO = -1 //单纯的监控,不做分析 TYPE_RUNTYPE_POLL = 0 //轮询做任务 TYPE_RUNTYPE_REALTIME = 1 //实时做任务 Camera_Status_NoRule = 0 //未配规则 Camera_Status_Wait = 1 //等待处理 Camera_Status_Doing = 2 //处理中 Camera_Status_Other = -1 //其他情况 Camera_Status_Err = -2 //故障 ) type Camera struct { VideoId int64 `gorm:"-;primaryKey;autoIncrement"` //摄像机id Id string `gorm:"column:id;type:varchar(100);unique;" json:"id"` Name string `gorm:"column:name" json:"name" bind:"required"` Alias string `gorm:"column:alias" json:"alias"` //摄像机的别名 SnapshotUrl string `gorm:"column:snapshot_url" json:"snapshot_url"` //快照地址 Type int `gorm:"column:type" json:"type" ` Addr string `gorm:"column:addr" json:"addr"` Longitude float32 `gorm:"column:longitude" json:"longitude"` Latitude float32 `gorm:"column:latitude" json:"latitude"` Floor int `gorm:"column:floor" json:"floor"` //楼层 Rtsp string `gorm:"column:rtsp" json:"rtsp"` Ip string `gorm:"column:ip" json:"ip"` Port int `gorm:"column:port" json:"port"` Username string `gorm:"column:username" json:"username"` Password string `gorm:"column:password" json:"password"` Brand string `gorm:"column:brand" json:"brand"` Reserved string `gorm:"column:reserved" json:"reserved"` IsRunning bool `gorm:"column:is_running" json:"is_running"` //是否正在解码 RunEnable bool `gorm:"column:run_enable" json:"run_enable"` //控制实时处理或轮询处理的开关 RunType int `gorm:"column:run_type" json:"run_type"` //处理类型:0:轮询,1:实时,-1:无任务,不做分析或者分析任务被关了 RunServerId string `gorm:"column:run_server_id" json:"run_server_id"` //当前正在处理的分析服务器id ResolutionWidth int `gorm:"column:resolution_width;default:0" json:"resolution_width"` //分辨率宽 ResolutionHeight int `gorm:"column:resolution_height;default:0" json:"resolution_height"` //分辨率高 VoiceEnable bool `gorm:"column:voiceEnable;default:0" json:"voiceEnable"` VoiceId string `gorm:"column:voiceId" json:"voiceId"` CoordTransform string `gorm:"column:coordTransform" json:"coordTransform"` //坐标转换,长春追踪reid用 } type CameraDto struct { VideoId int64 `gorm:"primaryKey;autoIncrement"` //摄像机id Id string `gorm:"column:id;type:varchar(100);unique;" json:"id"` Name string `gorm:"column:name" json:"name" bind:"required"` Alias string `gorm:"column:alias" json:"alias"` //摄像机的别名 SnapshotUrl string `gorm:"column:snapshot_url" json:"snapshot_url"` //快照地址 Type int `gorm:"column:type" json:"type" ` Addr string `gorm:"column:addr" json:"addr"` Longitude float32 `gorm:"column:longitude" json:"longitude"` Latitude float32 `gorm:"column:latitude" json:"latitude"` Floor int `gorm:"column:floor" json:"floor"` //楼层 Rtsp string `gorm:"column:rtsp" json:"rtsp"` Ip string `gorm:"column:ip" json:"ip"` Port int `gorm:"column:port" json:"port"` Username string `gorm:"column:username" json:"username"` Password string `gorm:"column:password" json:"password"` Brand string `gorm:"column:brand" json:"brand"` Reserved string `gorm:"column:reserved" json:"reserved"` IsRunning bool `gorm:"column:is_running" json:"is_running"` //是否正在解码 RunEnable bool `gorm:"column:run_enable" json:"run_enable"` //控制实时处理或轮询处理的开关 RunType int `gorm:"column:run_type" json:"run_type"` //处理类型:0:轮询,1:实时,-1:无任务,不做分析或者分析任务被关了 RunServerId string `gorm:"column:run_server_id" json:"run_server_id"` //当前正在处理的分析服务器id ResolutionWidth int `gorm:"column:resolution_width;default:0" json:"resolution_width"` //分辨率宽 ResolutionHeight int `gorm:"column:resolution_height;default:0" json:"resolution_height"` //分辨率高 VoiceEnable bool `gorm:"column:voiceEnable;default:0" json:"voiceEnable"` VoiceId string `gorm:"column:voiceId" json:"voiceId"` CoordTransform string `gorm:"column:coordTransform" json:"coordTransform"` //坐标转换,长春追踪reid用 } func (Camera) TableName() string { return "cameras" } type CameraTreeNode struct { Id string `json:"id"` Areaid string `json:"areaid"` Name string `json:"name"` CameraType int `json:"cameratype"` //是本地还是国标 Rtsp string `json:"rtsp"` } type Resolution struct { Width int `json:"width"` Height int `json:"height"` } func (camera *Camera) GetIdNameMap() map[string]string { cameraEMap := make(map[string]string, 0) allCams, err := camera.FindAll() if err == nil && allCams != nil && len(allCams) > 0 { for _, model := range allCams { cameraEMap[model.Id] = model.Name } } return cameraEMap } // cameraType (0:查全部,1:分析摄像机,2:监控摄像机) // cameraName func (camera *Camera) Find(cameraType int, cameraName string, camType int, isPlatform int, linkStr string) (camMenus []CameraTreeNode, err error) { logger.Debug("camType:", camType) cType := strconv.Itoa(camType) var sql = "select c.id,ca.areaid as areaid,case ifnull(c.alias,'') when '' then c.name else c.alias end as name,c.type as cameratype,c.rtsp from camera_area ca join cameras c on ca.cameraid=c.id where c.type=" + cType + "" if cameraName != "" { sql += " and c.name like '%" + cameraName + "%'" } if cameraType == 1 { //查分析摄像机 sql += " and (c.run_type=" + strconv.Itoa(TYPE_RUNTYPE_POLL) + " or c.run_type=" + strconv.Itoa(TYPE_RUNTYPE_REALTIME) + ")" } else if cameraType == 2 { //查监控摄像机 sql += " and c.run_type=" + strconv.Itoa(TYPE_RUNTYPE_VIDEO) + "" } else if cameraType == 3 { //查联动摄像机 //sql += " and c.id in (select crga.camera_id from camera_rule_group_arg crga join camera_task_link ctl on crga.group_id=ctl.link_task_id)" sql += " and c.id in (" + linkStr + ")" } if camType == TYPE_LOCAL_CAMERA { //国标的始终显示整棵树,本地树本机查本机,平台查所有 if isPlatform == 0 { //查本机 sql += " and c.run_server_id='" + config.Server.AnalyServerId + "'" } } sql += " order by c.id asc" if err := db.Raw(sql).Scan(&camMenus).Error; err != nil { return nil, err } return camMenus, nil } func (camera *Camera) FindAllByServer(serverId string, cameraName string, cameraType int, cameraId string, areaId string, linkWhere string) (list []Camera, err error) { var sql = "select * from cameras where 1=1 " if serverId != "" { sql += " and (run_server_id='" + serverId + "' or (run_server_id ='' or run_server_id is NULL))" } if cameraName != "" { sql += " and name like '%" + cameraName + "%'" } if cameraId != "" { sql += " and id='" + cameraId + "'" } if areaId != "" { sql += " and id in (select cameraId from camera_area where areaId='" + areaId + "')" } if cameraType == 1 { //查分析摄像机 sql += " and (run_type=" + strconv.Itoa(TYPE_RUNTYPE_POLL) + " or run_type=" + strconv.Itoa(TYPE_RUNTYPE_REALTIME) + ")" } else if cameraType == 2 { //查监控摄像机 sql += " and run_type=" + strconv.Itoa(TYPE_RUNTYPE_VIDEO) + "" } else if cameraType == 3 { //查联动摄像机 //规则配置进程独立后,此条件需要到规则进程中查询 sql += " and id in (" + linkWhere + ")" } if err := db.Raw(sql).Scan(&list).Error; err != nil { return nil, err } return list, nil } func (camera *Camera) GetCamerasByRunType(runType int, cameraName string) (list []Camera, err error) { analyServerId := config.Server.AnalyServerId //当前分析服务器的id(analyServerId,在配置文件中) sql := "select * from cameras where run_type=? and run_server_id=? " if cameraName != "" { sql = sql + " and name like ?" } if err := db.Raw(sql, runType, analyServerId, "%"+cameraName+"%").Scan(&list).Error; err != nil { return nil, err } return list, nil } func (camera *Camera) FindCamerasByType(typ int, runServerId string) (list []Camera, err error) { sql := "select * from cameras where type=? " if runServerId != "" { sql += " and run_server_id='" + runServerId + "'" } if err := db.Raw(sql, typ).Scan(&list).Error; err != nil { return nil, err } return list, nil } func (camera *Camera) Insert() (err error) { tx := db.Table("cameras").Begin() if tx.Error != nil { return err } if err := tx.Create(&camera).Error; err != nil { tx.Rollback() return err } //新增摄像机成功,发布消息 err = tx.Commit().Error return err } func (camera *Camera) SelectById(cameraId string) (rows int64, err error) { dbselect := db.Table(camera.TableName()).Where("id = ?", cameraId).First(&camera) if dbselect.Error != nil || dbselect.RowsAffected == 0 { return 0, err } return dbselect.RowsAffected, nil } func (camera *Camera) FindByRtsp(rtsp string) (cams []Camera, err error) { dbselect := db.Table(camera.TableName()).Where("rtsp = ?", rtsp).Find(&cams) if dbselect.Error != nil { return nil, dbselect.Error } return cams, nil } func (camera *Camera) FindAll() (cams []Camera, err error) { dberr := db.Table("cameras").Find(&cams) if dberr.Error != nil { return nil, err } return cams, nil } func (camera *Camera) FindAllMap() map[string]Camera { m := make(map[string]Camera, 0) cams, err := camera.FindAll() if err == nil && cams != nil { for _, model := range cams { m[model.Id] = model } } return m } func (camera *Camera) Update() (err error) { logger.Debug("camera:", camera) longitude := fmt.Sprintf("%3.4f", camera.Longitude) latitude := fmt.Sprintf("%3.4f", camera.Latitude) voiceEnable := 0 if camera.VoiceEnable { voiceEnable = 1 } sql := "update cameras set name='" + camera.Name + "',alias='" + camera.Alias + "',type=" + strconv.Itoa(camera.Type) + ",addr='" + camera.Addr + "',longitude=" + longitude + ",latitude=" + latitude + ",rtsp='" + camera.Rtsp + "',ip='" + camera.Ip + "',port=" + strconv.Itoa(camera.Port) + ",username='" + camera.Username + "',password='" + camera.Password + "',brand='" + camera.Brand + "',reserved='" + camera.Reserved + "',run_server_id='" + camera.RunServerId + "',resolution_width=" + strconv.Itoa(camera.ResolutionWidth) + ",resolution_height=" + strconv.Itoa(camera.ResolutionHeight) + ",voiceEnable=" + strconv.Itoa(voiceEnable) + ",voiceId='" + camera.VoiceId + "' where id='" + camera.Id + "'" if err := db.Exec(sql).Error; err != nil { return err } camera.AddDbChangeMsg(camera.Id, protomsg.DbAction_Update) return nil } func (camera *Camera) UpdateRunEnable(cameraId string, runEnable bool) bool { result := db.Exec("update cameras set run_enable=? where id=?", runEnable, cameraId) if result.Error != nil { return false } return result.RowsAffected > 0 } func (camera *Camera) ChangeRunType(cameraId string, runType int) bool { result := db.Exec("update cameras set run_type=? where id=?", runType, cameraId) if result.Error != nil { return false } return result.RowsAffected > 0 } func (camera *Camera) UpdateIsRunningState(cameraId string, isRunning bool) bool { isRunningStr := "0" if isRunning { isRunningStr = "1" } result := db.Exec("update cameras set is_running=" + isRunningStr + " where id='" + cameraId + "'") if result.Error != nil { return false } return result.RowsAffected > 0 } func (camera *Camera) UpdateIsRunningAll(camIds []string) bool { analyServerId := config.Server.AnalyServerId sql := "update cameras set is_running=0 where run_server_id='" + analyServerId + "'" uIds := "" if camIds != nil { for _, id := range camIds { uIds = uIds + "'" + id + "'," } } uIds = strings.Trim(uIds, ",") if uIds != "" { sql += " and id not in (" + uIds + ");update cameras set is_running=1 where run_server_id='" + analyServerId + "' and id in (" + uIds + ");" } logger.Debug("UpdateIsRunningAll sql:", sql) result := db.Exec(sql) if result.Error != nil { return false } return true } func (camera *Camera) UpdateSnapshot(cameraId string, snapshot string) bool { result := db.Exec("update cameras set snapshot_url=? where id=?", snapshot, cameraId) if result.Error != nil { return false } return result.RowsAffected > 0 } func (camera *Camera) Delete(cid string) (int64, error) { var err error tx := GetDB().Begin() defer func() { if err != nil && tx != nil { tx.Rollback() } }() dbdel := tx.Exec("delete from cameras where id=?", cid) err = dbdel.Error if err != nil || dbdel.RowsAffected == 0 { return 0, err } //if err = tx.Exec("delete from camera_polygon where camera_id=?",cid).Error;err !=nil{ // return 0,err //} if err = tx.Exec("delete from camera_area where cameraId=?", cid).Error; err != nil { return 0, err } if err = tx.Exec("delete from camera_sensor where camera_id=?", cid).Error; err != nil { return 0, err } tx.Commit() //发布数据更改消息 camera.AddDbChangeMsg(cid, protomsg.DbAction_Delete) return dbdel.RowsAffected, nil } func (camera *Camera) FindBy(isOnMap bool, floor int, cameraName string) (camArr []Camera, err error) { if isOnMap { sql := "select * from cameras where floor!=" + strconv.Itoa(Default_Layer) + "" if floor != Default_Layer { sql = sql + " and floor =" + strconv.Itoa(Default_Layer) + "" } err = db.Raw(sql).Scan(&camArr).Error } else { err = db.Raw("select * from cameras where (floor=" + strconv.Itoa(Default_Layer) + " or longitude<=0 or latitude<=0)").Scan(&camArr).Error } if err != nil { return nil, err } else { return camArr, nil } } func (camera *Camera) UpdatePos(id string, floor int, longitude float32, latitude float32) bool { result := db.Exec("update cameras set floor=?,longitude=?,latitude=? where id=?", floor, longitude, latitude, id) if result.Error != nil { return false } return result.RowsAffected > 0 } func (camera *Camera) UpdateCoordTrans(id string, coords string) bool { result := db.Exec("update cameras set coordTransform=? where id=?", coords, id) if result.Error != nil { return false } if result.RowsAffected > 0 { camera.AddDbChangeMsg(id, protomsg.DbAction_Update) return true } return false } func (camera *Camera) AddDbChangeMsg(chCamId string, action protomsg.DbAction) { bytes, _ := json.Marshal(camera) dbMsg := protomsg.DbChangeMessage{ Table: protomsg.TableChanged_T_Camera, Id: chCamId, Action: action, Info: string(bytes), } pub.AddDbMessage(&dbMsg) } type VideoLink struct { ID int `gorm:"column:id" json:"id"` VideoId string `gorm:"column:video_id" json:"videoId"` TaskId int `gorm:"column:task_id" json:"taskId"` } func GetTasks() map[string][]interface{} { var lists []VideoLink sqlStr := `select id,video_id,task_id from mal_task_video_link` if err := db.Raw(sqlStr).Scan(&lists).Error; err != nil { fmt.Println(err.Error()) return nil } checkMap := make(map[string][]interface{}) for _, d2 := range lists { if d2.VideoId != "" { checkMap[d2.VideoId] = append(checkMap[d2.VideoId], d2) } } return checkMap }