package controllers import ( "basic.com/dbapi.git" "basic.com/fileServer/WeedFSClient.git" "basic.com/pubsub/protomsg.git" "basic.com/valib/logger.git" "encoding/base64" "io/ioutil" "sort" "strconv" "time" "webserver/cache" "webserver/service" "github.com/gin-gonic/gin" "webserver/extend/code" "webserver/extend/config" "webserver/extend/util" "webserver/models" esApi "basic.com/pubsub/esutil.git" ) type DbPersonController struct { } // @Security ApiKeyAuth // @Summary 添加底库人员 // @Description 添加底库人员 // @Accept json // @Produce json // @Tags dbperson 底库人员 // @Param obj body models.Dbtablepersons true "底库人员数据" // @Success 200 {string} json "{"code":200, msg:"目录结构数据", success:true}" // @Failure 500 {string} json "{"code":500, msg:"返回错误信息", success:false}" // @Router /data/api-v/dbperson/addDbPerson [PUT] func (dbc DbPersonController) AddDbPerson(c *gin.Context) { dbperson := new(models.Dbtablepersons) err := c.BindJSON(&dbperson) if err!=nil || dbperson.TableId == "" { // 底库id不存在 util.ResponseFormat(c,code.RequestParamError,"参数有误") return } var pApi dbapi.DbPersonApi paramBody := util.Struct2Map(dbperson) b, data := pApi.AddDbPerson(paramBody) if b { util.ResponseFormat(c, code.AddSuccess, data) } else { util.ResponseFormat(c, code.ComError, "") } } type MultiCarNo struct { TableId string `json:"tableId" binding:"required"` CarNos []string `json:"carNos" binding:"required"` } // @Security ApiKeyAuth // @Summary 批量添加底库车辆 // @Description 批量添加底库车辆 // @Accept json // @Produce json // @Tags dbperson 底库人员 // @Param reqBody body controllers.MultiCarNo true "批量车牌号" // @Success 200 {string} json "{"code":200, msg:"", success:true}" // @Failure 500 {string} json "{"code":500, msg:"", success:false}" // @Router /data/api-v/dbperson/multiUploadCarNo [post] func (dbc DbPersonController) MultiUploadCarNo(c *gin.Context) { var reqBody MultiCarNo err := c.BindJSON(&reqBody) if err != nil { util.ResponseFormat(c, code.RequestParamError, "") return } logger.Debug("multiUploadCarNo reqBody:", reqBody) var pApi dbapi.DbPersonApi paramBody := util.Struct2Map(reqBody) if pApi.MultiUploadCarNo(paramBody) { util.ResponseFormat(c,code.UploadSuccess,"上传成功") } else { util.ResponseFormat(c,code.ComError,"") } } func addDbPerson(dbperson *models.Dbtablepersons) (result map[string]interface{}) { dbperson.PriInsert() var pApi dbapi.DbPersonApi paramBody := util.Struct2Map(dbperson) b, d := pApi.AddDbPerson(paramBody) result = map[string]interface{}{} if b { result["code"] = 200 personMap := util.Struct2Map(d) data := make(map[string]interface{}) data["uuid"] = personMap["id"] result["data"] = data result["success"] = true result["msg"] = "添加成功" } else { result["data"] = nil result["success"] = false result["msg"] = "服务器异常" result["code"] = 500 } return result } // @Security ApiKeyAuth // @Summary 修改底库人员 // @Description 修改底库人员 // @Accept json // @Produce json // @Tags dbperson 底库人员 // @Param person body models.Dbtablepersons true "底库人员数据" // @Success 200 {string} json "{"code":200, msg:"目录结构数据", success:true}" // @Failure 500 {string} json "{"code":500, msg:"返回错误信息", success:false}" // @Router /data/api-v/dbperson/updateDbPerson [POST] func (dbc DbPersonController) UpdateDbPerson(c *gin.Context) { var dbperson models.Dbtablepersons err := c.BindJSON(&dbperson) if err !=nil || dbperson.Id == "" { util.ResponseFormat(c, code.RequestParamError, nil) return } dbperson.PriUpdate() var pApi dbapi.DbPersonApi paramBody := util.Struct2Map(dbperson) b, data := pApi.UpdateDbPerson(paramBody) if b { util.ResponseFormat(c, code.UpdateSuccess, data) } else { util.ResponseFormat(c, code.UpdateFail, "") } } // @Security ApiKeyAuth // @Summary 底库人员以图搜图 // @Description 底库人员以图搜图 // @Accept json // @Produce json // @Tags dbperson 底库人员 // @Param condition body models.EsSearch true "底库以图搜图参数" // @Success 200 {string} json "{"code":200, msg:"", success:true}" // @Failure 500 {string} json "{"code":500, msg:"", success:false}" // @Router /data/api-v/dbperson/queryDbPersonsByCompare [POST] func (dbc DbPersonController) QueryDbPersonsByCompare(c *gin.Context) { var searchBody models.EsSearch err := c.BindJSON(&searchBody) if err !=nil || searchBody.PicUrl == "" || len(searchBody.DataBases) == 0{ util.ResponseFormat(c, code.RequestParamError, "参数有误") return } var faceB []byte if face,ok := faceExtractedMap[searchBody.PicUrl];!ok{ util.ResponseFormat(c, code.RequestParamError, "请重新上传图片") return } else { faceB = face.FaceBytes } analyServerId := "" conf, e := cache.GetServerInfo() if e ==nil && conf.ServerId != "" { analyServerId = conf.ServerId } else { util.ResponseFormat(c, code.ComError, "analyServerId为空,配置有误") return } arg := protomsg.CompareArgs{ FaceFeature: faceB, CompareThreshold: searchBody.Threshold, } arg.TableIds = searchBody.DataBases arg.AnalyServerId = analyServerId compareService := service.NewFaceCompareService(arg) var totalData service.CompareList dbPersonTargets := compareService.CompareDbPersons() if dbPersonTargets !=nil { totalData = append(totalData,*dbPersonTargets...) } service.SetCompResultByNum(&service.CompareOnce{ CompareNum: compareService.CompareNum, CompareData: &totalData, }) m := make(map[string]interface{},3) if totalData != nil && totalData.Len() > 0{ sort.Sort(totalData) total := totalData.Len() m["compareNum"] = compareService.CompareNum m["total"] = total var sCompResult protomsg.SdkCompareResult if total <= searchBody.Size { sCompResult.CompareResult = totalData } else { sCompResult.CompareResult = totalData[0:searchBody.Size] } resultList := FillDbPersonDataToCompareResult(&sCompResult) m["totalList"] = resultList } else { m["total"] = 0 m["compareNum"] = compareService.CompareNum m["totalList"] = []CompareResult{} } util.ResponseFormat(c,code.Success,m) } //填充向前端返回的数据 func FillDbPersonDataToCompareResult(compResult *protomsg.SdkCompareResult) []models.DbPersonsCompVo { var resultList = make([]models.DbPersonsCompVo, len(compResult.CompareResult)) dbPersonM := make(map[string]ScoreIndex, 0) personIds := make([]string,0) for idx,v :=range compResult.CompareResult{ dbPersonM[v.Id] = ScoreIndex{ Index: idx, CompareScore: float64(v.CompareScore), } personIds = append(personIds,v.Id) } logger.Debug("comp len(personIds):", len(personIds)) var dbpersons []protomsg.Dbperson if len(personIds) >0 { var dbpApi dbapi.DbPersonApi dbpersons, _ = dbpApi.Dbpersoninfosbyid(personIds) } if len(dbpersons) >0 { //var dtApi dbapi.DbTableApi for _,p :=range dbpersons { var dbP models.DbPersonsCompVo dbP.Id = p.Id dbP.TableId = p.TableId dbP.FaceFeature = p.FaceFeature dbP.PersonPicUrl = p.PersonPicUrl dbP.PersonName = p.PersonName dbP.Age = p.Age dbP.Sex = p.Sex dbP.IdCard = p.IdCard dbP.PhoneNum = p.PhoneNum dbP.MonitorLevel = p.MonitorLevel dbP.Reserved = p.Reserved dbP.IsDelete = int(p.IsDelete) dbP.Enable = int(p.Enable) dbP.CreateTime = p.CreateTime dbP.UpdateTime = p.UpdateTime dbP.CreateBy = p.CreateBy dbP.CompareScore = dbPersonM[p.Id].CompareScore //dbTableInfos, _ := dtApi.DbtablesById([]string{ p.TableId }) //if dbTableInfos !=nil{ // dbP.BwType = dbTableInfos[0].BwType // dbP.TableName = dbTableInfos[0].TableName //} resultList[dbPersonM[p.Id].Index] = dbP } } return resultList } // @Security ApiKeyAuth // @Summary 更新底库人脸照片 // @Description 更新底库人脸照片 // @Accept multipart/form-data // @Produce json // @Tags dbperson 底库人员 // @Param id formData string true "人员id" // @Param file formData file true "人脸图片" // @Success 200 {string} json "{"code":200, msg:"", success:true}" // @Failure 500 {string} json "{"code":500, msg:"", success:false}" // @Router /data/api-v/dbperson/updateFace [POST] func (dbc DbPersonController) UpdateFace(c *gin.Context) { file, header, err := c.Request.FormFile("file") id := c.Request.FormValue("id") if err != nil || id == "" { util.ResponseFormat(c,code.RequestParamError,"参数有误") return } //文件的名称 filename := header.Filename defer file.Close() // weedfs 上传 fileBytes, err := ioutil.ReadAll(file) if err !=nil { util.ResponseFormat(c,code.ComError,"图片读取失败") return } //将上传的图片交人脸检测和人脸提取,获得特征 var faceBase64="" faceArr, err, pI := service.GetFaceFeaFromSdk(fileBytes, time.Second*5) if faceArr ==nil { util.ResponseFormat(c,code.ComError,"未到提取人脸") return } var rcFace *protomsg.Rect if err ==nil && len(faceArr) >0 { if len(faceArr) >1 { util.ResponseFormat(c,code.ComError,"人脸大于一张,请换一张人脸图片") return } for _,r := range faceArr { //拿到人脸的坐标 rcFace = r.Pos.RcFace faceBase64 = base64.StdEncoding.EncodeToString(r.Feats)//获取提取到的第一张人脸特征 break } } localConf, err2 := cache.GetServerInfo() if err2 !=nil || localConf.WebPicIp == "" { logger.Debug("localConfig is wrong!!!") return } var weedfsUri = "http://"+localConf.WebPicIp+":"+strconv.Itoa(int(localConf.WebPicPort))+"/submit?collection=persistent" //根据人脸坐标扣出人脸小图 t1 := time.Now() cutFaceImgData,_ := util.SubCutImg(pI, rcFace, 20) logger.Debug("SubImg用时:", time.Since(t1)) t1 = time.Now() weedFilePath, e := WeedFSClient.UploadFile(weedfsUri, filename, cutFaceImgData) logger.Debug("上传到weedfs用时:", time.Since(t1)) t1 = time.Now() if e != nil { util.ResponseFormat(c,code.ComError,"人脸上传失败") return } m := map[string]interface{} { "faceFeature": faceBase64, "personPicUrl": weedFilePath, } util.ResponseFormat(c,code.Success, m) //var dbpApi dbapi.DbPersonApi //b,d := dbpApi.UpdateFace(id,faceBase64,weedFilePath) //if b { // util.ResponseFormat(c,code.UpdateSuccess,d) //} else { // util.ResponseFormat(c,code.UpdateFail,"更新人脸失败") //} } // @Security ApiKeyAuth // @Summary 删除底库人员 // @Description 删除库人员 // @Accept x-www-form-urlencoded // @Produce json // @Tags dbperson 底库人员 // @Param uuid path string true "底库人员id " // @Success 200 {string} json "{"code":200, msg:"目录结构数据", success:true}" // @Failure 500 {string} json "{"code":500, msg:"返回错误信息", success:false}" // @Router /data/api-v/dbperson/deleteDbPersonById/{uuid} [POST] func (dbc DbPersonController) DeleteDbPerson(c *gin.Context) { id := c.Params.ByName("uuid") if id == "" { util.ResponseFormat(c,code.RequestParamError,"参数有误") return } var pApi dbapi.DbPersonApi b, data := pApi.DeleteDbPerson(id) if b { util.ResponseFormat(c, code.Success, data) } else { util.ResponseFormat(c, code.ServiceInsideError, "删除失败") } } type DelMultiPerson []string // @Security ApiKeyAuth // @Summary 删除底库人员 // @Description 删除库人员 // @Accept json // @Produce json // @Tags dbperson 底库人员 // @Param uuids body controllers.DelMultiPerson true "底库人员ids " // @Success 200 {string} json "{"code":200, msg:"目录结构数据", success:true}" // @Failure 500 {string} json "{"code":500, msg:"返回错误信息", success:false}" // @Router /data/api-v/dbperson/deleteMoreDbPerson [POST] func (dbc DbPersonController) DeleteMoreDbPerson(c *gin.Context) { var uuids DelMultiPerson err := c.BindJSON(&uuids) if err !=nil || len(uuids)==0{ util.ResponseFormat(c,code.RequestParamError,"参数有误") return } logger.Debug("DeleteMoreDbPerson len(uuids):",len(uuids)) var pApi dbapi.DbPersonApi m := map[string]interface{}{ "ids": uuids, } b, _ := pApi.DeleteMoreDbPerson(m) if b { util.ResponseFormat(c, code.Success, "删除底库人员成功") } else { util.ResponseFormat(c, code.ServiceInsideError, "删除失败") } } // @Security ApiKeyAuth // @Summary 查询底库人员列表 // @Description 查询库人员列表 // @Accept json // @Produce json // @Tags dbperson 底库人员 // @Param reqMap body controllers.DbtSearch false "{"tableId":"","orderName":"id","orderType":"desc","contentValue":"","page":1,"size":8}" // @Success 200 {string} json "{"code":200, "msg":"目录结构数据", "success":true,"data":{}}" // @Failure 500 {string} json "{code:500, msg:"返回错误信息", success:false,data:{}}" // @Router /data/api-v/dbperson/queryDbPersonsByTbId [POST] func (dbc DbPersonController) QueryDbPersonsByTbId(c *gin.Context) { //reqBody := make(map[string]interface{}, 5) var reqBody DbtSearch err := c.BindJSON(&reqBody) if err !=nil || reqBody.Page <=0 || reqBody.Size <=0 { util.ResponseFormat(c,code.RequestParamError,"参数有误") return } if reqBody.TableId == "" { util.ResponseFormat(c,code.RequestParamError,"参数有误,底库id不能为空") return } orderName := "id" if reqBody.OrderName != "" { orderName = reqBody.OrderName } // 列名 orderType := "desc" if reqBody.OrderType != "" { orderType = reqBody.OrderType } //搜索内容 contentValue := reqBody.ContentValue page := 1 if reqBody.Page >1 { page = reqBody.Page } // 页码 size := 8 if reqBody.Size >8 { size = reqBody.Size } // 条数 if orderType == "desc" { orderType = "desc" } else { orderType = "asc" } var pApi dbapi.DbPersonApi paramBody := map[string]interface{}{ "tableId": reqBody.TableId, "orderName":orderName, "orderType":orderType, "contentValue":contentValue, "page":page, "size":size, } b, data := pApi.QueryDbPersonsByTbId(paramBody) if b{ util.ResponseFormat(c,code.Success,data) } else { util.ResponseFormat(c,code.ComError,[]interface{}{}) } } type JoinDbTVo struct { CaptureId string `json:"captureId"` TableIds []string `json:"tableIds"` } // @Security ApiKeyAuth // @Summary 抓拍人员加入底库 // @Description 抓拍人员加入底库 // @Accept json // @Produce json // @Tags dbperson 底库人员 // @Param obj body controllers.JoinDbTVo true "底库数据" // @Success 200 {string} json "{"code":200, msg:"目录结构数据", success:true}" // @Failure 500 {string} json "{"code":500, msg:"返回错误信息", success:false}" // @Router /data/api-v/dbperson/joinDbTable [POST] func (dbc *DbPersonController) JoinDbTable(c *gin.Context) { var reqBody JoinDbTVo c.BindJSON(&reqBody) if reqBody.CaptureId == "" || len(reqBody.TableIds) ==0 { util.ResponseFormat(c,code.RequestParamError, "参数有误") return } localConf, err := cache.GetServerInfo() if err !=nil || localConf.AlarmIp == "" || localConf.AlarmPort <=0 { util.ResponseFormat(c,code.ComError,"报警设置有误") return } aiOceans, e := esApi.AIOceaninfosbyid([]string{reqBody.CaptureId}, config.EsInfo.EsIndex.AiOcean.IndexName, localConf.AlarmIp, strconv.Itoa(int(localConf.AlarmPort))) if e ==nil && aiOceans !=nil && len(aiOceans) == 1{ var personPicUrl = ""//人脸图片 var feature = ""//特征 if aiOceans[0].TargetInfo !=nil && len(aiOceans[0].TargetInfo) >0 { personPicUrl = aiOceans[0].TargetInfo[0].PicSmUrl } fea, e2 := esApi.GetVideoPersonFaceFeatureById(reqBody.CaptureId, config.EsInfo.EsIndex.AiOcean.IndexName, localConf.AlarmIp, strconv.Itoa(int(localConf.AlarmPort))) if e2 == nil && fea !="" { feature = fea } if personPicUrl != "" && feature != "" { //将这张抓拍的照片下载下来上传到collection=persistent的集合中,防止被清理掉 picB, e3 := util.DownLoad("http://" + personPicUrl) if e3 == nil { var weedfsUri = "http://"+localConf.WebPicIp+":"+strconv.Itoa(int(localConf.WebPicPort))+"/submit?collection=persistent" newPersonPicUrl, e4 := WeedFSClient.UploadFile(weedfsUri, "capturePerson", picB) if e4 == nil { var dbpApi dbapi.DbPersonApi b,d := dbpApi.JoinDbTable(reqBody.TableIds, feature, newPersonPicUrl) if b { util.ResponseFormat(c,code.Success,d) return } else { util.ResponseFormat(c,code.ComError,"加入失败") return } } } } } util.ResponseFormat(c,code.ComError,"加入失败") } type DbtSearch struct { TableId string `json:"tableId"` OrderName string `json:"orderName"` OrderType string `json:"orderType"` ContentValue string `json:"contentValue"` Page int `json:"page"` Size int `json:"size"` } type DbPersonMove struct { PersonId string `json:"personId"` TableIds []string `json:"tableIds"` } // @Security ApiKeyAuth // @Summary 人员移动 // @Description 人员移动 // @Accept json // @Produce json // @Tags dbperson 底库人员 // @Param obj body controllers.DbPersonMove true "移动参数" // @Success 200 {string} json "{"code":200, msg:"", success:true}" // @Failure 500 {string} json "{"code":500, msg:"", success:false}" // @Router /data/api-v/dbperson/move [POST] func (dbc *DbPersonController) Move(c *gin.Context) { var reqBody DbPersonMove c.BindJSON(&reqBody) if reqBody.PersonId == "" || len(reqBody.TableIds) == 0 { util.ResponseFormat(c,code.RequestParamError, "参数有误") return } var dbpApi dbapi.DbPersonApi b,d := dbpApi.Move(reqBody.PersonId, reqBody.TableIds) if b { util.ResponseFormat(c,code.Success,d) } else { util.ResponseFormat(c,code.ComError,"") } } // @Security ApiKeyAuth // @Summary 人员复制 // @Description 人员复制 // @Accept json // @Produce json // @Tags dbperson 底库人员 // @Param obj body controllers.DbPersonMove true "复制参数" // @Success 200 {string} json "{"code":200, msg:"", success:true}" // @Failure 500 {string} json "{"code":500, msg:"", success:false}" // @Router /data/api-v/dbperson/copy [POST] func (dbc *DbPersonController) Copy(c *gin.Context) { var reqBody DbPersonMove c.BindJSON(&reqBody) if reqBody.PersonId == "" || len(reqBody.TableIds) == 0 { util.ResponseFormat(c,code.RequestParamError, "参数有误") return } var dbpApi dbapi.DbPersonApi b,d := dbpApi.Copy(reqBody.PersonId, reqBody.TableIds) if b { util.ResponseFormat(c,code.Success,d) } else { util.ResponseFormat(c,code.ComError,"") } }