123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335 |
- package service
- import (
- "dy-admin/internal/pcmserver/bus/cabinet_pkg"
- "dy-admin/internal/pcmserver/bus/cabinet_pkg/dataProto"
- "dy-admin/internal/pcmserver/bus/model"
- "dy-admin/pkg/log"
- "go.uber.org/zap"
- "strconv"
- "sync"
- )
- var cabinetMapChannel *cabinetsChannel
- type cabinetChannel struct {
- cabinetConnectChan chan *dataProto.CabinetConnect
- gridStatusChan chan *dataProto.GridStatsProto
- openStatusChan chan *dataProto.GridLockStatusProto
- }
- type cabinetsChannel struct {
- cabinetMapChannel map[int]*cabinetChannel
- mutex *sync.Mutex
- }
- func newCabinetsChannel() {
- if cabinetMapChannel == nil {
- cabinetMapChannel = &cabinetsChannel{
- cabinetMapChannel: make(map[int]*cabinetChannel),
- mutex: &sync.Mutex{},
- }
- }
- }
- func (cc *cabinetsChannel) setCabinetChannel(cabinetId int) *cabinetChannel {
- cc.mutex.Lock()
- defer cc.mutex.Unlock()
- channels := &cabinetChannel{
- cabinetConnectChan: make(chan *dataProto.CabinetConnect),
- gridStatusChan: make(chan *dataProto.GridStatsProto, 1024),
- openStatusChan: make(chan *dataProto.GridLockStatusProto, 1024),
- }
- go watchChannel(cabinetId, channels)
- cc.cabinetMapChannel[cabinetId] = channels
- return channels
- }
- func (cc *cabinetsChannel) deleteCabinetChannel(cabinetId int) {
- cc.mutex.Lock()
- defer cc.mutex.Unlock()
- channels, ok := cc.cabinetMapChannel[cabinetId]
- if !ok {
- return
- }
- close(channels.cabinetConnectChan)
- close(channels.gridStatusChan)
- close(channels.openStatusChan)
- }
- func watchChannel(cabinetId int, channels *cabinetChannel) {
- for {
- select {
- // 推送柜子连接信息
- case connectInfo, ok := <-channels.cabinetConnectChan:
- if !ok {
- return
- }
- var dbConnected = "断开"
- if connectInfo.IsConnected {
- dbConnected = "连接"
- }
- // 数据库更新
- err := ServicesGroupApp.CabinetService.ChangeCabinetConnectStatus(cabinetId, dbConnected)
- if err != nil {
- log.Error("update cabinet connect err", zap.Error(err))
- continue
- }
- // 推送格子状态,关门后触发
- case gridStatusInfo, ok := <-channels.gridStatusChan:
- if !ok {
- return
- }
- deviceGridId := int(gridStatusInfo.GridNumber)
- // 获取格子信息
- grid, err := ServicesGroupApp.GridService.GetGridByCabinetIDAndGridID(cabinetId, deviceGridId)
- if err != nil {
- log.Error("get grid err", zap.Error(err))
- continue
- }
- oldGridStore := grid.StoneState
- // 格子的状态
- if grid.Staff.ID == 0 {
- // 格子未被占用。什么都不记录
- log.Info("grid.staff is nil,do nothing", zap.Any("gridStatusInfo", gridStatusInfo))
- continue
- }
- // 格子被占用,将设备推送的格子信息转换为本地格子信息
- grid.ChargeState = model.GridRechargeMap[gridStatusInfo.CellStatus]
- grid.OpenState = model.GridOpenStateMap[gridStatusInfo.LockStatus]
- grid.StoneState = model.GridStoneStateMap[gridStatusInfo.StoreStatus]
- grid.RFID = strconv.FormatUint(uint64(gridStatusInfo.RFID), 10)
- // 如果之前的就是存物未登记,不重复执行更新格子和记录日志
- //if grid.StoneState == oldGridStore && oldGridStore == model.GridStoneStateMap[model.GridNoMatchStoneCode] {
- // log.Info("物品未登记,重复记录", zap.Int("CabinetID", grid.CabinetID), zap.Int("DeviceGridID", grid.DeviceGridID))
- // continue
- //}
- // 格子最终状态判断和日志记录
- processGridStatus(&grid, oldGridStore)
- err = ServicesGroupApp.GridService.UpdateGrid(grid)
- if err != nil {
- log.Error("update gird open status err", zap.Error(err))
- continue
- }
- // 推送柜门状态,开门响应
- case openStatus, ok := <-channels.openStatusChan:
- if !ok {
- return
- }
- deviceGridId := int(openStatus.GridNumber)
- // 获取格子信息
- grid, err := ServicesGroupApp.GridService.GetGridByCabinetIDAndGridID(cabinetId, deviceGridId)
- if err != nil {
- log.Error("get grid err", zap.Error(err))
- continue
- }
- if grid.Staff.ID == 0 {
- // 格子未被占用。什么都不记录
- log.Info("grid.staff is nil,do nothing", zap.Any("openStatusInfo", openStatus))
- continue
- }
- grid.OpenState = model.GridOpenStateMap[openStatus.LockStatus]
- processOpenGridStatus(&grid)
- err = createOpenLog(&grid)
- if err != nil {
- log.Error("createOpenLog err", zap.Error(err))
- }
- // 更新格子门状态
- err = ServicesGroupApp.GridService.UpdateByCabinetIDAndGridID(model.Grid{
- CabinetID: cabinetId,
- DeviceGridID: deviceGridId,
- OpenState: model.GridOpenStateMap[openStatus.LockStatus],
- })
- if err != nil {
- log.Error("update gird open status err", zap.Error(err))
- continue
- }
- }
- }
- }
- // 根据当前推送的信息,判断格子最终状态。并记录日志
- func processGridStatus(grid *model.Grid, oldStoneStatus string) {
- // 判断是否报警逻辑
- cabinet := cabinet_pkg.GetCabinet(grid.CabinetID)
- if cabinet == nil {
- log.Error("processGridStatus cabinet is nil")
- return
- }
- var iswarn bool
- // 如果格子中的人员为请假
- if grid.Staff.VacationState == 2 {
- // 柜子人员为请假状态
- grid.ColorStatus = "黄色"
- grid.GridInfo = "请假中"
- } else {
- if grid.StoneState == model.GridStoneStateMap[model.GridNoStoneStateCode] {
- // 格子未存物
- if !cabinet.IsAllowOpen {
- // 柜子不允许开 并且未存物 -报警
- // 报警
- iswarn = true
- grid.ColorStatus = "红色"
- if oldStoneStatus == model.GridStoneStateMap[model.GridNoStoneStateCode] || oldStoneStatus == "" {
- // 之前格子就没存入
- grid.GridInfo = "未存入"
- } else if oldStoneStatus == model.GridStoneStateMap[model.GridStoneStateCode] {
- // 之前格子有,现在没了,被视为取出
- grid.GridInfo = "非正常取出"
- }
- } else {
- // 柜子允许开 未存物 -正常
- grid.ColorStatus = "绿色"
- grid.GridInfo = "已取出"
- }
- } else if grid.StoneState == model.GridStoneStateMap[model.GridStoneStateCode] {
- // 格子存物了
- grid.ColorStatus = "绿色"
- grid.GridInfo = grid.ChargeState
- } else if grid.StoneState == model.GridStoneStateMap[model.GridNoMatchStoneCode] {
- // 物品未登记
- iswarn = true
- grid.ColorStatus = "红色"
- grid.GridInfo = grid.StoneState
- }
- }
- var err error
- if iswarn {
- err = createWarnLog(grid)
- if err != nil {
- log.Error("createWarnLog err", zap.Error(err))
- }
- go func() {
- memInfo := cabinet_pkg.GetCabinet(grid.CabinetID)
- err = sendDeptWarnLog(memInfo.DeptID, true, nil)
- if err != nil {
- log.Error("sendUpdateCabinetOpenStatus", zap.Error(err))
- }
- }()
- }
- err = createStoreLog(grid)
- if err != nil {
- log.Error("createStoreLog err", zap.Error(err))
- }
- err = createOpenLog(grid)
- if err != nil {
- log.Error("createOpenLog err", zap.Error(err))
- }
- }
- // 根据开门响应推送的信息,记录是否报警的日志
- func processOpenGridStatus(grid *model.Grid) {
- // 判断是否报警逻辑
- cabinet := cabinet_pkg.GetCabinet(grid.CabinetID)
- if cabinet == nil {
- log.Error("processGridStatus cabinet is nil")
- return
- }
- if cabinet_pkg.IsHumanization() {
- if grid.Staff.VacationState == 2 {
- return
- }
- // 人性化管理时,不允许开门时打开门,记录警告日志
- if !cabinet.IsAllowOpen {
- // 柜子当前是不允许开的,发出警告
- grid.ColorStatus = "红色"
- grid.GridInfo = "在规定时间以外开门"
- err := createWarnLog(grid)
- if err != nil {
- log.Error("createWarnLog err", zap.Error(err))
- }
- go func() {
- memInfo := cabinet_pkg.GetCabinet(grid.CabinetID)
- err = sendDeptWarnLog(memInfo.DeptID, true, nil)
- if err != nil {
- log.Error("sendUpdateCabinetOpenStatus", zap.Error(err))
- }
- }()
- }
- }
- // 任何时候,如果出现非指令开锁,报警
- if grid.OpenState == model.GridNoCmdState {
- grid.ColorStatus = "红色"
- grid.GridInfo = model.GridNoCmdState
- err := createWarnLog(grid)
- if err != nil {
- log.Error("createWarnLog err", zap.Error(err))
- }
- go func() {
- memInfo := cabinet_pkg.GetCabinet(grid.CabinetID)
- err = sendDeptWarnLog(memInfo.DeptID, true, nil)
- if err != nil {
- log.Error("sendUpdateCabinetOpenStatus", zap.Error(err))
- }
- }()
- }
- }
- func createWarnLog(grid *model.Grid) error {
- lg := model.GridWarnLog{
- DepartmentID: grid.Staff.DepartmentID,
- DepartmentName: grid.Staff.DeptName,
- StaffID: grid.Staff.ID,
- StaffName: grid.Staff.Name,
- CabinetID: grid.CabinetID,
- CabinetName: grid.Staff.CabinetName,
- GridDeviceID: grid.DeviceGridID,
- WarnState: grid.GridInfo,
- }
- err := ServicesGroupApp.GridWarnLogService.CreateGridWarnLog(lg)
- return err
- }
- func createStoreLog(grid *model.Grid) error {
- lg := model.GridStoreLog{
- DepartmentID: grid.Staff.DepartmentID,
- DepartmentName: grid.Staff.DeptName,
- StaffID: grid.Staff.ID,
- StaffName: grid.Staff.Name,
- CabinetID: grid.CabinetID,
- CabinetName: grid.Staff.CabinetName,
- GridDeviceID: grid.DeviceGridID,
- StoreState: grid.StoneState,
- }
- err := ServicesGroupApp.GridStoreLogService.CreateGridStoreLog(lg)
- return err
- }
- func createOpenLog(grid *model.Grid) error {
- lg := model.GridOpenLog{
- DepartmentID: grid.Staff.DepartmentID,
- DepartmentName: grid.Staff.DeptName,
- StaffID: grid.Staff.ID,
- StaffName: grid.Staff.Name,
- CabinetID: grid.CabinetID,
- CabinetName: grid.Staff.CabinetName,
- GridDeviceID: grid.DeviceGridID,
- OpenState: grid.OpenState,
- }
- err := ServicesGroupApp.GridOpenLogService.CreateGridOpenLog(lg)
- return err
- }
|