liuxiaolong
2022-03-04 f64dd9f191dff341b4eb430d7bacc44a3db9a279
service/carService.go
@@ -7,6 +7,9 @@
   "encoding/json"
   "fmt"
   "github.com/astaxie/beego"
   "sort"
   "strconv"
   "strings"
)
type CarService struct {
   hikUtil *reqUtil.HikHttpUtil
@@ -15,8 +18,8 @@
func NewCarService() *CarService {
   return &CarService{
      hikUtil: &reqUtil.HikHttpUtil{
         AppKey: hikAppKey,
         AppSecret: hikAppSecret,
         AppKey: beego.AppConfig.String("hikAppKey"),
         AppSecret: beego.AppConfig.String("hikAppSecret"),
         ReqHost: beego.AppConfig.String("hikUrl"),
      },
   }
@@ -24,25 +27,27 @@
func (sv *CarService) Statistic() (*models.CarStatistic, bool) {
   m := models.CarStatistic{
      TotalPermPlace: 0,
      Left:           0,
      TotalPlace: 0,
      Left:       0,
   }
   parkList := sv.getHikParkList() //先查有几个停车场
   flag := false
   if parkList != nil {
      flag = true
      for _,p := range parkList {
         remainList := sv.getRemainSpaceNum(p.ParkIndexCode)
         if remainList != nil {
            for _,r := range remainList {
               m.Left += r.LeftPlace
               m.TotalPermPlace += r.LeftPermPlace
            }
   //20201117 修改统计方式,按照  剩余车位数=车位总数-车库内实际停车数(页面上显示的,不含vip车辆占位)
   spaceInfo := sv.FindSpaceNo("")
   if spaceInfo != nil {
      m.TotalPlace = len(spaceInfo)
      usedCount := 0
      for _,si := range spaceInfo {
         if si.State == 1 {
            usedCount++
         }
      }
      m.Left = m.TotalPlace-usedCount
      if m.Left < 0 {
         m.Left = 0
      }
      return &m, true
   } else {
      return &m, false
   }
   return &m, flag
}
type ParkInfo struct {
@@ -52,11 +57,6 @@
   CreateTime             string          `json:"createTime"`
   UpdateTime             string          `json:"updateTime"`
}
var (
   hikAppKey = "27107808"
   hikAppSecret = "BEQiCoBTYcJX2d4KzbVK"
)
//获取海康停车库列表
@@ -93,12 +93,12 @@
   ParkSysCode          string          `json:"parkSyscode"`        //停车库唯一标识码
   ParkName             string          `json:"parkName"`           //停车库名称
   ParentParkSyscode       string          `json:"parentParkSyscode"`  //父停车库唯一标识
   TotalPlace             int          `json:"totalPlace"`        //停车库车位总数
   TotalPermPlace          int          `json:"totalPermPlace"`    //停车库固定车位总数
   TotalReservePlace       int          `json:"totalReservePlace"` //停车位预约车位总数
   LeftPlace             int          `json:"leftPlace"`     //停车库车位剩余数
   LeftPermPlace          int          `json:"leftPermPlace"` //停车库固定车位剩余数
   LeftReservePlace       int          `json:"leftReservePlace"` //停车库预约车位剩余数
   TotalPlace             int          `json:"totalPlace"`         //停车库车位总数
   TotalPermPlace          int          `json:"totalPermPlace"`     //停车库固定车位总数
   TotalReservePlace       int          `json:"totalReservePlace"`  //停车位预约车位总数
   LeftPlace             int          `json:"leftPlace"`            //停车库车位剩余数
   LeftPermPlace          int          `json:"leftPermPlace"`      //停车库固定车位剩余数
   LeftReservePlace       int          `json:"leftReservePlace"`   //停车库预约车位剩余数
}
func (sv *CarService) getRemainSpaceNum(parkIndexCode string) []RemainSpaceResult {
@@ -146,69 +146,325 @@
   PlateNoPicUri          string       `json:"plateNoPicUri"`
   AswSyscode             string       `json:"aswSyscode"`
   PlateNos            string       `json:"plateNos"`
   PlateNo               string       `json:"plateNo"`
   AlarmPlateNos          string       `json:"alarmPlateNos"`
   SpaceType             string       `json:"spaceType"`
}
func (sv *CarService) FindHikSpaceInfo(userId string) []SpaceNo {
   url := "/artemis/api/pms/v1/parkingSpace/spaceNo"
   reqBody := map[string]interface{} {
      "pageNo": 1,
      "pageSize": 1000,
   }
   pageResult := sv.getHikPageResult(url, reqBody)
   if pageResult != nil {
      rb, err := json.Marshal(pageResult.List)
      if err != nil {
         fmt.Println("marshal pageResult.List err:", err)
         return nil
      }
      var spaceList []SpaceNo
      err = json.Unmarshal(rb, &spaceList)
      if err != nil {
         fmt.Println("unmarshal spaceNos err:", err)
         return nil
      } else {
         curLoginManagerPhone := ""
         personMap := sv.GetHikPersonMap()
         if userId != "" {
            if mm,ok := personMap[userId];ok {
               curLoginManagerPhone = mm.PhoneNo
            }
         }
         isSuper := false
         if curLoginManagerPhone != "" {
            superPhoneArr := strings.Split(beego.AppConfig.String("superManagerPhones"), ",")
            if superPhoneArr != nil {
               for _,sp := range superPhoneArr {
                  if sp == curLoginManagerPhone { //是超级管理员
                     isSuper = true
                     break
                  }
               }
            }
         }
         vipPlateNoArr := getVipPlateNoArr()
         var resultArr []SpaceNo
         for _,si := range spaceList {
            if si.State == 1 &&si.PlateNo != "" && si.PlateNo != "无车牌" { //有车
               if isSuper {
                  resultArr = append(resultArr, si)
               } else {
                  if isSpaceShow(vipPlateNoArr, si.PlateNo) {
                     resultArr = append(resultArr, si)
                  }
               }
            }
         }
         return resultArr
      }
   }
   return nil
}
type SpaceUser struct {
   SpaceNo    string          `json:"spaceNo"`
   PlateNo    string          `json:"plateNo"`
   Username    string          `json:"username"`
   PhoneNum    string          `json:"phoneNum"`
   CarType    string          `json:"carType"`
}
type SpaceUserArr []SpaceUser
func (arr SpaceUserArr) Len()int {
   return len(arr)
}
func (arr SpaceUserArr) Swap(i,j int) {
   arr[i],arr[j] = arr[j],arr[i]
}
func (arr SpaceUserArr) Less(i,j int) bool {
   sn1,_ := strconv.Atoi(arr[i].SpaceNo)
   sn2,_ := strconv.Atoi(arr[j].SpaceNo)
   return sn1 < sn2
}
func (sv *CarService) FindHikSpaceUser(userId string) SpaceUserArr {
   resultList := make(SpaceUserArr, 0)
   url := "/artemis/api/pms/v1/parkingSpace/spaceNo"
   reqBody := map[string]interface{} {
      "pageNo": 1,
      "pageSize": 1000,
   }
   pageResult := sv.getHikPageResult(url, reqBody)
   if pageResult != nil {
      rb, err := json.Marshal(pageResult.List)
      if err != nil {
         fmt.Println("marshal pageResult.List err:", err)
      } else {
         var spaceList []SpaceNo
         err = json.Unmarshal(rb, &spaceList)
         if err != nil {
            fmt.Println("unmarshal spaceNos err:", err)
         } else {
            if len(spaceList) > 0 { //当前有停留车
               personMap := sv.GetHikPersonMap()
               vehicleMap := sv.GetHikVehicleMap()
               curLoginManagerPhone := ""
               if userId != "" {
                  if mm,ok := personMap[userId];ok {
                     curLoginManagerPhone = mm.PhoneNo
                  }
               }
               isSuper := false
               if curLoginManagerPhone != "" {
                  superPhoneArr := strings.Split(beego.AppConfig.String("superManagerPhones"), ",")
                  if superPhoneArr != nil {
                     for _,sp := range superPhoneArr {
                        if sp == curLoginManagerPhone { //是超级管理员
                           isSuper = true
                           break
                        }
                     }
                  }
               }
               vipPlateNoArr := getVipPlateNoArr()
               for _,sp := range spaceList {
                  if sp.State == 1 && sp.PlateNo != "" && sp.PlateNo != "无车牌"{
                     su := SpaceUser{
                        SpaceNo: sp.SpaceNo,
                        PlateNo: sp.PlateNo,
                     }
                     if sp.PlateNo != "" {
                        r := []rune(sp.PlateNo)
                        ncStr := string(r[1:]) //把第一位汉字剔除掉
                        newK := strings.ReplaceAll(ncStr, "D", "*")
                        newK = strings.ReplaceAll(newK, "0", "*")
                        personId := ""
                        if v,exist := vehicleMap[newK]; exist {
                           personId = v.PersonId
                        }
                        if personId != "" {
                           su.CarType = "备案车"
                           if person, in := personMap[personId]; in {
                              su.Username = person.PersonName
                              su.PhoneNum = person.PhoneNo
                           }
                        } else {
                           su.CarType = "临时车"
                        }
                     } else {
                        su.PlateNo = "无车牌"
                     }
                     if isSuper {
                        resultList = append(resultList, su)
                     } else {
                        if isSpaceShow(vipPlateNoArr, su.PlateNo) {
                           resultList = append(resultList, su)
                        }
                     }
                  }
               }
            }
         }
      }
   }
   sort.Sort(resultList)
   return resultList
}
func getVipPlateNoArr() []string {
   var vipPlateNoArr []string
   vipArr := strings.Split(beego.AppConfig.String("nightVipPlateNos"), ",")
   if vipArr != nil && len(vipArr) >0 {
      for _,po := range vipArr {
         if po != "" {
            cnPo := preDealPlateNo(po)
            if cnPo != "" {
               vipPlateNoArr = append(vipPlateNoArr, cnPo)
            }
         }
      }
   }
   return vipPlateNoArr
}
//白天和夜晚管理员都看不到vip车辆
func isSpaceShow(vipPlateNoArr []string, spacePto string) bool {
   if vipPlateNoArr != nil && len(vipPlateNoArr) >0 {
      targetPto := preDealPlateNo(spacePto)
      if isVipCar(targetPto, vipPlateNoArr) { //是vip车辆
         return false
      }
   }
   return true
}
func (sv *CarService) FindSpaceNo(userId string) models.PosResult {
   resultList := make(models.PosResult,0)
   var myPlateNosMap = make(map[string]string)
   vehicles := sv.GetVehicleListByPerson(userId)
   if vehicles != nil {
      for _,veh := range vehicles {
         myPlateNosMap[veh.PlateNo] = veh.PlateNo
         //myPlateNos = append(myPlateNos, veh.PlateNo)
   if userId !="" {
      vehicles := sv.GetVehicleListByPerson(userId)
      if vehicles != nil {
         for _,veh := range vehicles {
            if veh.PlateNo != ""{
               r := []rune(veh.PlateNo)
               ncStr := string(r[1:]) //把第一位汉字剔除掉
               myPlateNosMap[ncStr] = ncStr
            }
            //myPlateNosMap[veh.PlateNo] = veh.PlateNo
         }
      }
   }
   //bindCars := strings.Join(myPlateNos, ",")
   //先查车库唯一标识
   //parkList := sv.getHikParkList() //先查有几个停车场
   //if parkList != nil {
      url := "/artemis/api/pms/v1/parkingSpace/spaceNo"
      //for _,p := range parkList {
         reqBody := map[string]interface{} {
            //"parkSyscode": p.ParkIndexCode,//停车库唯一标识
            //"state": 1, //车位状态,0:空闲,1:停车
            //"bindCars": bindCars,
            "pageNo": 1,
            "pageSize": 1000,
   url := "/artemis/api/pms/v1/parkingSpace/spaceNo"
   reqBody := map[string]interface{} {
      //"parkSyscode": p.ParkIndexCode,//停车库唯一标识
      //"state": 1, //车位状态,0:空闲,1:停车
      //"bindCars": bindCars,
      "pageNo": 1,
      "pageSize": 1000,
   }
   pageResult := sv.getHikPageResult(url, reqBody)
   //fmt.Println("findSpaceNo pageResult:", pageResult)
   if pageResult != nil {
      rb, err := json.Marshal(pageResult.List)
      if err != nil {
         fmt.Println("marshal pageResult.List err:",err)
         return nil
      }
      var spaceList []SpaceNo
      err = json.Unmarshal(rb, &spaceList)
      if err != nil {
         fmt.Println("unmarshal spaceNos err:",err)
         return nil
      }
      vipPlateNoArr := getVipPlateNoArr()
      for _,s := range spaceList {
         pi := models.PosInfo {
            SpaceNo: s.SpaceNo,
            PosNo: "",
            State: s.State,
         }
         pageResult := sv.getHikPageResult(url, reqBody)
         fmt.Println("findSpaceNo pageResult:", pageResult)
         if pageResult != nil {
            rb, err := json.Marshal(pageResult.List)
            if err != nil {
               fmt.Println("marshal pageResult.List err:",err)
               return nil
            }
            var spaceList []SpaceNo
            err = json.Unmarshal(rb, &spaceList)
            if err != nil {
               fmt.Println("unmarshal spaceNos err:",err)
               return nil
            }
            for _,s := range spaceList {
               isMine := false
               if _,exist := myPlateNosMap[s.PlateNos]; exist {
                  isMine = true
               }
               pi := models.PosInfo {
                  SpaceNo: s.SpaceNo,
                  PosNo: "",
                  State: s.State,
                  PlateNo: s.PlateNos,
                  IsMine: isMine,
               }
               if v,ok := models.SpaceNo2Pos[s.SpaceNo];ok {
                  pi.PosNo = v
               }
               resultList = append(resultList, pi)
            }
         if s.PlateNo != "" {
            pi.PlateNo = s.PlateNo
         } else if s.PlateNos != "" {
            pi.PlateNo = s.PlateNos
         }
      //}
   //}
            if pi.PlateNo == "无车牌" {
            pi.State = 0
            pi.PlateNo = ""
            resultList = append(resultList, pi)
            } else {
             pi.IsMine = isMyPlateNo(myPlateNosMap, pi.PlateNo)
             if v,ok := models.SpaceNo2Pos[s.SpaceNo];ok {
                pi.PosNo = v
             }
              if isSpaceShow(vipPlateNoArr, pi.PlateNo) {
                resultList = append(resultList, pi)
             } else {
                pi.State = 0
                pi.PlateNo = ""
                resultList = append(resultList, pi)
             }
            }
      }
   }
   if len(resultList) == 0 {
      for i:=1;i<91;i++ {
         pi := models.PosInfo {
            SpaceNo: strconv.Itoa(i),
            PosNo: "",
            State: 1,
            PlateNo: "",
            IsMine: false,
         }
         resultList = append(resultList, pi)
      }
   }
   return resultList
}
//判断是不是自己的车牌号
//1.目前有误识别的问题,会把D识别成0,D和0不分
//2.汉字误识别的几率比较高
func isMyPlateNo(plateNoM map[string]string, targetPlateNo string) bool {
   if targetPlateNo != "" && plateNoM != nil {
      r := []rune(targetPlateNo)
      nctPlateNo := string(r[1:])
      if _,exist := plateNoM[nctPlateNo];exist {
         return true
      } else {
         match := false
         for k,_ := range plateNoM {
            newK := strings.ReplaceAll(k, "D", "*")
            newK = strings.ReplaceAll(newK, "0", "*")
            tt := strings.ReplaceAll(nctPlateNo,"D", "*")
            tt = strings.ReplaceAll(tt,"0", "*")
            if newK == tt {
               match = true
               break
            }
         }
         return match
      }
   }
   return false
}
func (sv *CarService) BindCarSpace() bool {
@@ -243,6 +499,37 @@
   PicUri                      string             `json:"picUri"`
   ServerIndexCode             string             `json:"serverIndexCode"`
   PersonId                   string             `json:"personId"`
}
//以人员id为key
func (sv *CarService) GetHikPersonMap() map[string]HikPerson {
   m := make(map[string]HikPerson)
   personList := sv.GetHikPersonList()
   if personList != nil {
      for _,p := range personList {
         m[p.PersonId] = p
      }
   }
   return m
}
//以车牌号为Key
func (sv *CarService) GetHikVehicleMap() map[string] HikVehicle {
   m := make(map[string]HikVehicle)
   carPersons := sv.GetVehicleListByPerson("")
   if carPersons != nil {
      for _,veh := range carPersons {
         if veh.PlateNo != "" {
            r := []rune(veh.PlateNo)
            ncStr := string(r[1:]) //把第一位汉字剔除掉
            newK := strings.ReplaceAll(ncStr, "D", "*")
            newK = strings.ReplaceAll(newK, "0", "*")
            m[newK] = veh
         }
      }
   }
   return m
}
func (sv *CarService) GetHikPersonList() []HikPerson {
@@ -297,10 +584,38 @@
   return list
}
func SyncHikPerson() int {
   syncCount := 0
   sv := NewCarService()
   hikPersons := sv.GetHikPersonList()
   if hikPersons != nil && len(hikPersons) >0 {
      var u models.User
      idMap := u.GetAllMap()
      hikPM := make(map[string]string)
      for _,hp := range hikPersons {
         hikPM[hp.PersonId] = hp.PhoneNo
         if sp,ok := idMap[hp.PersonId];ok {
            if sp.PhoneNum != hp.PhoneNo {
               u.UpdatePhoneNum(hp.PhoneNo, hp.PersonId)
               syncCount++
            }
         }
      }
      for k,_ := range idMap {
         if _,in := hikPM[k];!in {
            u.Delete(k)
            syncCount++
         }
      }
   }
   return syncCount
}
func (sv *CarService) getHikPageResult(url string, reqBody map[string]interface{}) *vo.HikPageResult {
   fmt.Println(url, reqBody)
   result := sv.hikUtil.Post(url, reqBody)
   if result.Code == reqUtil.HikResult_Success {
   if result != nil && result.Code == reqUtil.HikResult_Success {
      b, err := json.Marshal(result.Data)
      if err == nil {
         var pageResult vo.HikPageResult
@@ -344,11 +659,14 @@
   url := "/artemis/api/resource/v2/vehicle/advance/vehicleList"
   reqBody := map[string]interface{} {
      "pageNo": 1,
      "pageSize": 100,
      "personIds": personId,
      "pageSize": 1000,
   }
   if personId != "" {
      reqBody["personIds"] = personId
   }
   pageResult := sv.getHikPageResult(url, reqBody)
   if pageResult ==nil {
      fmt.Println("GetVehicleListByPerson pageResult is nil")
      return nil
   }
@@ -357,8 +675,61 @@
      var list []HikVehicle
      if err = json.Unmarshal(b, &list);err == nil {
         return list
      } else {
         fmt.Println("unmarshal err:", err)
      }
   }
   return nil
}
}
//过车记录
type CrossRecord struct {
   CrossRecordSyscode          string        `json:"crossRecordSyscode"`
   parkSyscode                 string        `json:"parkSyscode"`
   ParkName                    string        `json:"parkName"`
   EntranceSyscode             string        `json:"entranceSyscode"`
   EntranceName                string        `json:"entranceName"`
   RoadwaySyscode              string        `json:"roadwaySyscode"`
   RoadwayName                 string        `json:"roadwayName"`
   VehicleOut                  int           `json:"vehicleOut"`
   ReleaseMode                 int           `json:"releaseMode"`
   ReleaseResult               int           `json:"releaseResult"`
   ReleaseWay                  int           `json:"releaseWay"`
   ReleaseReason               int           `json:"releaseReason"`
   PlateNo                     string        `json:"plateNo"`
   CardNo                      string        `json:"cardNo"`
   //VehicleColor              int             `json:"vehicleColor"`
   //VehicleType               int             `json:"vehicleType"`
   //PlateColor                int             `json:"plateColor"`
   //PlateType                 int             `json:"plateType"`
   //CarCategory               string          `json:"carCategory"`
   //CarCategoryName           string          `json:"carCategoryName"`
   VehiclePicUri               string        `json:"vehiclePicUri"`
   PlateNoPicUri               string        `json:"plateNoPicUri"`
   FacePicUri                  string        `json:"facePicUri"`
   AswSyscode                  string        `json:"aswSyscode"`
   CrossTime                   string        `json:"crossTime"`
   CreateTime                  string        `json:"createTime"`
}
func (sv *CarService) CrossRecords() []CrossRecord {
   url := "/artemis/api/pms/v1/crossRecords/page"
   reqBody := map[string]interface{} {
      "pageNo": 1,
      "pageSize": 100,
   }
   pageResult := sv.getHikPageResult(url, reqBody)
   if pageResult ==nil {
      return nil
   }
   b, err := json.Marshal(pageResult.List)
   if err == nil {
      var list []CrossRecord
      if err = json.Unmarshal(b, &list);err == nil {
         return list
      }
   }
   return nil
}