terminal_manager.go 5.3 KB
package service

import (
	"container/list"
	"fmt"
	"github.com/gookit/event"
	"github.com/linmadan/egglib-go/utils/json"
	"gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/domain"
	"gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/log"
	"sync"
)

var (
	DownEntityEvent = "down_entity"
)

type TerminalManager struct {
	TerminalDeviceList []*TerminalDevice
	TerminalDevices    sync.Map
}

func NewTerminalManager() *TerminalManager {
	return &TerminalManager{
		TerminalDeviceList: make([]*TerminalDevice, 0),
		TerminalDevices:    sync.Map{},
	}
}

func (term *TerminalManager) GetDevice(terminalId string, params ...interface{}) (*TerminalDevice, bool) {
	device, ok := term.TerminalDevices.Load(terminalId)
	if !ok {
		var companyId int64
		if len(params) > 0 {
			companyId = params[0].(int64)
		}
		device := NewTerminalDevice(terminalId, companyId)
		term.TerminalDevices.Store(terminalId, device)
		log.Logger.Debug(fmt.Sprintf("【TerminalManager】 终端上线 add new device:%v", terminalId), map[string]interface{}{"device": device})
		term.TerminalDeviceList = append(term.TerminalDeviceList, device)
		return nil, false
	}
	if v, ok := device.(*TerminalDevice); ok {
		return v, ok
	}
	return nil, false
}
func (term *TerminalManager) PopDownEntityByDevice(sn string) (DownEntity, bool) {
	device, ok := term.GetDevice(sn)
	if !ok {
		return nil, false
	}
	return device.PopDownEntity()
}

func (term *TerminalManager) AddDownEntityByDevice(sn string, entity interface{}) bool {
	device, ok := term.GetDevice(sn)
	if !ok {
		return false
	}
	device.AddDownEntity(entity)
	return true
}

func (term *TerminalManager) BroadcastDownEntity(downEntity interface{}) {
	if len(term.TerminalDeviceList) == 0 {
		log.Logger.Debug("【TerminalManager】 当前在线终端:0 广播命令退出")
		return
	}
	for i := range term.TerminalDeviceList {
		term.TerminalDeviceList[i].AddDownEntity(downEntity)
	}
}

// Listen Event

func (term *TerminalManager) DownEntityEvent(e event.Event) error {
	entity := e.Get("entity")
	if entity != nil {
		term.BroadcastDownEntity(entity)
	}
	return nil
}

func (term *TerminalManager) SyncUser(e event.Event) error {
	user := e.Get("user")
	userBase := e.Get("userBase")
	if user != nil && userBase != nil {
		assertUser := user.(*domain.User)
		assertUserBase := userBase.(*domain.UserBase)
		if len(assertUser.Ext.IcCardNumber) == 0 {
			log.Logger.Debug("【TerminalManager】 当前用户ICCard未设置 不进行同步", map[string]interface{}{"user": user})
			return nil
		}
		term.BroadcastDownEntity(NewUpdateUserDownEntity(generateSn(), assertUser.Ext.IcCardNumber, assertUserBase.UserInfo.UserName))
		if len(assertUserBase.UserInfo.FacePortrait) > 0 {
			term.BroadcastDownEntity(NewUpdateUserFacePortraitDownEntity(generateSn(), assertUser.Ext.IcCardNumber, assertUserBase.UserInfo.FacePortrait, assertUser.CompanyId))
		}
		if len(assertUserBase.UserInfo.FingerprintPortrait) > 0 {
			term.BroadcastDownEntity(NewUpdateUserFingerprintPortraitDownEntity(generateSn(), assertUser.Ext.IcCardNumber, assertUserBase.UserInfo.FingerprintPortrait, assertUser.CompanyId))
		}
	}
	return nil
}

func (term *TerminalManager) EnableUser(e event.Event) error {
	user := e.Get("user")
	if user != nil {
		assertUser := user.(*domain.User)
		if assertUser.EnableStatus == int(domain.UserStatusEnable) {
			term.SyncUser(e)
		} else if assertUser.EnableStatus == int(domain.UserStatusDisable) {
			term.BroadcastDownEntity(NewDeleteDownEntity(generateSn(), assertUser.Ext.IcCardNumber, string(UserInfo), assertUser.CompanyId))
		}
	}
	return nil
}

func (term *TerminalManager) CreateUser(e event.Event) error {
	return term.SyncUser(e)
}

func (term *TerminalManager) UpdateUser(e event.Event) error {
	return term.EnableUser(e)
}

type TerminalDevice struct {
	Id             string
	CompanyId      int64
	DownEntityList *list.List
}

func NewTerminalDevice(terminalId string, companyId int64) *TerminalDevice {
	return &TerminalDevice{
		Id:             terminalId,
		CompanyId:      companyId,
		DownEntityList: list.New(),
	}
}

func (device *TerminalDevice) PopDownEntity() (DownEntity, bool) {
	element := device.DownEntityList.Front()
	if element == nil {
		return nil, false
	}
	device.DownEntityList.Remove(element)
	if v, ok := element.Value.(DownEntity); ok {
		log.Logger.Debug("【TerminalManager】 发送命令 pop down entity to Sender cmd:"+v.DownCommand(), map[string]interface{}{"entity": v})
		return v, ok
	}
	return nil, false
}

func (device *TerminalDevice) AddDownEntity(downEntity interface{}) {
	v, ok := downEntity.(DownEntity)
	var cmd string
	if !ok {
		return
	}
	cmd = v.DownCommand()
	options := objectJsonToMap(downEntity)
	if v, ok := options["CompanyId"]; ok {
		companyId, ok := v.(int64)
		if ok && device.CompanyId != companyId {
			log.Logger.Debug("【TerminalManager】 丢弃命令(公司不匹配) cmd:"+cmd, map[string]interface{}{"entity": downEntity, "device": device})
			return
		}
	}
	log.Logger.Debug("【TerminalManager】 添加命令 add down entity to Profile cmd:"+cmd, map[string]interface{}{"entity": downEntity})
	device.DownEntityList.PushBack(downEntity)
}

func objectJsonToMap(v interface{}) map[string]interface{} {
	result := make(map[string]interface{})
	data := json.MarshalToString(v)
	json.UnmarshalFromString(data, &result)
	return result
}