作者 yangfu

refactor: 优化数据同步

... ... @@ -61,10 +61,10 @@ func terminalReport(cmd *command.TerminalReportCommand, transactionContext appli
var (
response string = "OK"
)
log.Logger.Debug(fmt.Sprintf("【TerminalManager】 收到上行命令 command:%v table:%v content:%v", cmd.Command, cmd.Table, cmd.Content))
switch cmd.Command {
case "getrequest":
device, ok := GlobalTerminalManager.GetDevice(cmd.TerminalId)
device, ok := GlobalTerminalManager.GetDevice(cmd.TerminalId, cmd.CompanyId)
if !ok || device == nil {
break
}
... ... @@ -103,7 +103,6 @@ func terminalReport(cmd *command.TerminalReportCommand, transactionContext appli
break
}
case "devicecmd":
log.Logger.Debug("【TerminalManager】 收到命令应答 cmd : " + cmd.Content)
}
return map[string]interface{}{
... ... @@ -236,10 +235,10 @@ func (handler ZKClockHandler) Attendance(entity AttLOGUpEntity) (DownEntity, err
}
// 请求 人脸识别-指纹
if len(userBase.UserInfo.FingerprintPortrait) == 0 {
sendQuery = true
// sendQuery = true
}
if sendQuery {
event.Fire(DownEntityEvent, map[string]interface{}{"entity": NewQueryUserInfoDownEntity(generateSn(), entity.Pin)})
event.Fire(DownEntityEvent, map[string]interface{}{"entity": NewQueryUserInfoDownEntity(generateSn(), entity.Pin, entity.CompanyId)})
}
return nil, nil
}
... ... @@ -260,14 +259,20 @@ func (handler ZKClockHandler) BioData(entity BIODATAEntity) (DownEntity, error)
return nil, err
}
// 请求 人脸识别-用户画像
if len(userBase.UserInfo.FacePortrait) == 0 && len(entity.Tmp) > 0 && entity.Type == "9" {
if len(entity.Tmp) > 0 && entity.Type == "9" {
userBase.UserInfo.FacePortrait = entity.Tmp
updateFlag = true
if len(GlobalTerminalManager.TerminalDeviceList) >= 1 { //TODO:后期移除掉,多台设备时才进行广播
event.Fire(DownEntityEvent, map[string]interface{}{"entity": NewUpdateUserFacePortraitDownEntity(generateSn(), entity.Pin, entity.Tmp, entity.CompanyId)})
}
}
// 请求 人脸识别-指纹
if len(userBase.UserInfo.FingerprintPortrait) == 0 && len(entity.Tmp) > 0 && entity.Type == "1" {
if len(entity.Tmp) > 0 && entity.Type == "1" {
userBase.UserInfo.FingerprintPortrait = entity.Tmp
updateFlag = true
if len(GlobalTerminalManager.TerminalDeviceList) >= 1 {
event.Fire(DownEntityEvent, map[string]interface{}{"entity": NewUpdateUserFingerprintPortraitDownEntity(generateSn(), entity.Pin, entity.Tmp, entity.CompanyId)})
}
}
if updateFlag {
_, err = userBaseRepository.Save(userBase)
... ...
... ... @@ -2,7 +2,9 @@ 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"
... ... @@ -24,12 +26,16 @@ func NewTerminalManager() *TerminalManager {
}
}
func (term *TerminalManager) GetDevice(terminalId string) (*TerminalDevice, bool) {
func (term *TerminalManager) GetDevice(terminalId string, params ...interface{}) (*TerminalDevice, bool) {
device, ok := term.TerminalDevices.Load(terminalId)
if !ok {
device := NewTerminalDevice(terminalId)
var companyId int64
if len(params) > 0 {
companyId = params[0].(int64)
}
device := NewTerminalDevice(terminalId, companyId)
term.TerminalDevices.Store(terminalId, device)
log.Logger.Debug("【TerminalManager】 终端上线 add new device:"+terminalId, map[string]interface{}{"device": 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
}
... ... @@ -38,7 +44,6 @@ func (term *TerminalManager) GetDevice(terminalId string) (*TerminalDevice, bool
}
return nil, false
}
func (term *TerminalManager) PopDownEntityByDevice(sn string) (DownEntity, bool) {
device, ok := term.GetDevice(sn)
if !ok {
... ... @@ -79,32 +84,20 @@ func (term *TerminalManager) DownEntityEvent(e event.Event) error {
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)
if assertUser.Ext.DepName != "制造中心" {
log.Logger.Debug("【TerminalManager】 当前用户部门不是 [制造中心] 不进行同步", map[string]interface{}{"user": user})
return nil
}
term.BroadcastDownEntity(NewUpdateUserDownEntity(generateSn(), assertUser.Ext.IcCardNumber, assertUser.Ext.UserName))
return nil
}
if user != nil && userBase != nil {
assertUser := user.(*domain.User)
assertUserBase := userBase.(*domain.UserBase)
if assertUser.Ext.DepName != "制造中心" {
log.Logger.Debug("【TerminalManager】 当前用户部门不是 [制造中心] 不进行同步", map[string]interface{}{"user": user})
return nil
}
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))
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))
term.BroadcastDownEntity(NewUpdateUserFingerprintPortraitDownEntity(generateSn(), assertUser.Ext.IcCardNumber, assertUserBase.UserInfo.FingerprintPortrait, assertUser.CompanyId))
}
term.BroadcastDownEntity(NewUpdateUserDownEntity(generateSn(), assertUser.Ext.IcCardNumber, assertUserBase.UserInfo.UserName))
}
return nil
}
... ... @@ -116,7 +109,7 @@ func (term *TerminalManager) EnableUser(e event.Event) error {
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)))
term.BroadcastDownEntity(NewDeleteDownEntity(generateSn(), assertUser.Ext.IcCardNumber, string(UserInfo), assertUser.CompanyId))
}
}
return nil
... ... @@ -132,12 +125,14 @@ func (term *TerminalManager) UpdateUser(e event.Event) error {
type TerminalDevice struct {
Id string
CompanyId int64
DownEntityList *list.List
}
func NewTerminalDevice(terminalId string) *TerminalDevice {
func NewTerminalDevice(terminalId string, companyId int64) *TerminalDevice {
return &TerminalDevice{
Id: terminalId,
CompanyId: companyId,
DownEntityList: list.New(),
}
}
... ... @@ -158,9 +153,25 @@ func (device *TerminalDevice) PopDownEntity() (DownEntity, bool) {
func (device *TerminalDevice) AddDownEntity(downEntity interface{}) {
v, ok := downEntity.(DownEntity)
var cmd string
if ok {
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
}
... ...
... ... @@ -13,6 +13,21 @@ var (
BIODATA TableType = "BIODATA" //一体化数据 (人脸识别等)
)
type BioDataType int
var (
BioDataType0 BioDataType = 0 //通用
BioDataType1 BioDataType = 1 //指纹
BioDataType2 BioDataType = 0 //面部
BioDataType3 BioDataType = 3 //声纹
BioDataType4 BioDataType = 4 //虹膜
BioDataType5 BioDataType = 5 //视网膜
BioDataType6 BioDataType = 6 //掌纹
BioDataType7 BioDataType = 7 //指静脉
BioDataType8 BioDataType = 8 //手掌
BioDataType9 BioDataType = 9 //可见光面部
)
// AttLOGUpEntity 打卡记录实体 - 上行命令
type AttLOGUpEntity struct {
Pin string
... ... @@ -90,39 +105,29 @@ func QueryUserInfoRequest(sn string, entity AttLOGUpEntity) string {
type QueryUserInfoDownEntity struct {
Sn string
Pin string
CompanyId int64
}
func (entity QueryUserInfoDownEntity) DownCommand() string {
return fmt.Sprintf("C:%v:DATA QUERY USERINFO PIN=%v", entity.Sn, entity.Pin)
}
func NewQueryUserInfoDownEntity(sn string, pin string) QueryUserInfoDownEntity {
func NewQueryUserInfoDownEntity(sn string, pin string, companyId int64) QueryUserInfoDownEntity {
return QueryUserInfoDownEntity{
Sn: sn,
Pin: pin,
CompanyId: companyId,
}
}
type BioDataType int
var (
BioDataType0 BioDataType = 0 //通用
BioDataType1 BioDataType = 1 //指纹
BioDataType2 BioDataType = 0 //面部
BioDataType3 BioDataType = 3 //声纹
BioDataType4 BioDataType = 4 //虹膜
BioDataType5 BioDataType = 5 //视网膜
BioDataType6 BioDataType = 6 //掌纹
BioDataType7 BioDataType = 7 //指静脉
BioDataType8 BioDataType = 8 //手掌
BioDataType9 BioDataType = 9 //可见光面部
)
// QueryBioDataDownEntity 查询一体化-下行命令
type QueryBioDataDownEntity struct {
Sn string
Pin string
Type BioDataType
CompanyId int64
}
func (entity QueryBioDataDownEntity) DownCommand() string {
... ... @@ -142,13 +147,15 @@ type DeleteDownEntity struct {
Sn string
Pin string
Table string
CompanyId int64
}
func (entity DeleteDownEntity) DownCommand() string {
return fmt.Sprintf("C:%v:DATA DELETE %v PIN=%v", entity.Sn, entity.Table, entity.Pin)
}
func NewDeleteDownEntity(sn string, pin string, t string) DeleteDownEntity {
func NewDeleteDownEntity(sn string, pin string, t string, companyId int64) DeleteDownEntity {
return DeleteDownEntity{
Sn: sn,
Pin: pin,
... ... @@ -162,6 +169,8 @@ type UpdateUserDownEntity struct {
Pin string
Name string
Card string
CompanyId int64
}
func (entity UpdateUserDownEntity) DownCommand() string {
... ... @@ -181,13 +190,15 @@ type UpdateUserFacePortraitDownEntity struct {
Sn string
Pin string
FacePortrait string
CompanyId int64
}
func (entity UpdateUserFacePortraitDownEntity) DownCommand() string {
return fmt.Sprintf("C:%v:DATA UPDATE BIODATA Pin=%v\tNo=0\tType=9\tMajorVer=39\tMinorVer=1\tFormat=0\tIndex=0\tValid=1\tDuress=0\tTmp=%v", entity.Sn, entity.Pin, entity.FacePortrait)
}
func NewUpdateUserFacePortraitDownEntity(sn string, pin string, facePortrait string) UpdateUserFacePortraitDownEntity {
func NewUpdateUserFacePortraitDownEntity(sn string, pin string, facePortrait string, companyId int64) UpdateUserFacePortraitDownEntity {
return UpdateUserFacePortraitDownEntity{
Sn: sn,
Pin: pin,
... ... @@ -200,13 +211,15 @@ type UpdateUserFingerprintPortraitDownEntity struct {
Sn string
Pin string
FingerprintPortrait string
CompanyId int64
}
func (entity UpdateUserFingerprintPortraitDownEntity) DownCommand() string {
return fmt.Sprintf("C:%v:DATA UPDATE FINGERTMP PIN=%v\tFID=5\tSize=%v\tValid=1\tTMP=%v", entity.Sn, entity.Pin, len([]byte(entity.FingerprintPortrait)), entity.FingerprintPortrait)
}
func NewUpdateUserFingerprintPortraitDownEntity(sn string, pin string, fingerprintPortrait string) UpdateUserFingerprintPortraitDownEntity {
func NewUpdateUserFingerprintPortraitDownEntity(sn string, pin string, fingerprintPortrait string, companyId int64) UpdateUserFingerprintPortraitDownEntity {
return UpdateUserFingerprintPortraitDownEntity{
Sn: sn,
Pin: pin,
... ...
... ... @@ -11,7 +11,7 @@ import (
type SyncToAttendanceMachineCommand struct {
OperateInfo *domain.OperateInfo `json:"-"`
// 用户关联的角色
Users []int64 `cname:"用户关联的角色" json:"userIds" valid:"Required"`
Users []string `cname:"用户关联的角色" json:"userIds"`
}
func (syncToAttendance *SyncToAttendanceMachineCommand) Valid(validation *validation.Validation) {
... ...
... ... @@ -6,6 +6,7 @@ import (
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/application/factory"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/application/user/command"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/domain"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/infrastructure/utils"
"gitlab.fjmaimaimai.com/allied-creation/allied-creation-user/pkg/log"
)
... ... @@ -24,11 +25,24 @@ func (userService *UserService) SyncToAttendanceMachine(cmd *command.SyncToAtten
transactionContext.RollbackTransaction()
}()
userRepository, _, _ := factory.FastPgUser(transactionContext, 0)
_, users, err := userRepository.Find(map[string]interface{}{"companyId": cmd.OperateInfo.CompanyId, "inUserIds": cmd.Users})
//orgRepository, _, _ := factory.FastPgOrg(transactionContext, 0)
var users []*domain.User
// 指定用户进行同步
if len(cmd.Users) > 0 {
_, users, err = userRepository.Find(map[string]interface{}{"companyId": cmd.OperateInfo.CompanyId, "inUserIds": utils.ToArrayInt64(cmd.Users)})
if err != nil {
return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
}
} else {
//org, _ := orgRepository.FindOne(map[string]interface{}{"companyId": cmd.OperateInfo.CompanyId, "orgName": "制造中心"})
//if org == nil {
// return nil, nil
//}
_, users, err = userRepository.Find(map[string]interface{}{"companyId": cmd.OperateInfo.CompanyId, "icCardNumberNotEqual": ""})
if err != nil {
return nil, application.ThrowError(application.BUSINESS_ERROR, err.Error())
}
}
for i := range users {
_, userBase, err := factory.FastPgUserBase(transactionContext, users[i].UserBaseId)
... ...
... ... @@ -102,18 +102,25 @@ func (userService *UserService) BatchEnable(batchEnableCommand *command.BatchEna
}
for i := 0; i < len(batchEnableCommand.UserIds); i++ {
if user, err := userRepository.FindOne(map[string]interface{}{"userId": batchEnableCommand.UserIds[i]}); err != nil {
var (
user *domain.User
userBase *domain.UserBase
)
user, err = userRepository.FindOne(map[string]interface{}{"userId": batchEnableCommand.UserIds[i]})
if err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
} else {
}
if err := user.SetEnableStatus(batchEnableCommand.EnableStatus); err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
if _, err := userRepository.Save(user); err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
if err, _ := event.Fire(domain.UserEnableEvent, map[string]interface{}{"user": user}); err != nil {
if _, userBase, err = factory.FastPgUserBase(transactionContext, user.UserBaseId); err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
if err, _ := event.Fire(domain.UserEnableEvent, map[string]interface{}{"user": user, "userBase": userBase}); err != nil {
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
}
}
... ...
... ... @@ -213,6 +213,9 @@ func (repository *UserRepository) Find(queryOptions map[string]interface{}) (int
if v, ok := queryOptions["inCompanyIds"]; ok && len(v.([]int64)) > 0 {
query.Where(`company_id in (?)`, pg.In(v))
}
if v, ok := queryOptions["inDepartmentIds"]; ok && len(v.([]int64)) > 0 {
query.Where(`department_id in (?)`, pg.In(v))
}
query.SetWhereByQueryOption("user_code = ?", "userCode")
query.SetWhereByQueryOption("ext->>'icCardNumber' = ?", "icCardNumber")
query.SetWhereByQueryOption("user_base_id=?", "userBaseId")
... ... @@ -234,6 +237,9 @@ func (repository *UserRepository) Find(queryOptions map[string]interface{}) (int
if v, ok := queryOptions["cooperationCompany"]; ok && len(v.(string)) > 0 {
query.Where(fmt.Sprintf(`cooperation_info->>'cooperationCompany' like '%%%v%%'`, v))
}
if _, ok := queryOptions["icCardNumberNotEqual"]; ok {
query.Where(fmt.Sprintf(`ext->>'icCardNumber' <> '%v'`, ""))
}
query.SetOffsetAndLimit(domain.MaxQueryRow)
query.SetOrderDirect("user_id", "DESC")
if count, err := query.SelectAndCount(); err != nil {
... ...
... ... @@ -262,3 +262,12 @@ func CopyObject(src, dst interface{}) {
}
}
}
func ToArrayInt64(inputs []string) []int64 {
result := make([]int64, 0)
for i := range inputs {
v, _ := strconv.ParseInt(inputs[i], 10, 64)
result = append(result, v)
}
return result
}
... ...