package gate_match import ( "context" "encoding/json" "fmt" "git.getensh.com/common/gopkgs/cache" "git.getensh.com/common/gopkgs/database" "git.getensh.com/common/gopkgs/logger" "go.uber.org/zap" "google.golang.org/grpc/status" "gorm.io/gorm" "property-device/errors" dbmodel "property-device/model" "property-device/pb" pb_v1 "property-device/pb/v1" "property-device/utils/gate_utils" "strconv" ) func checkGateWhiteMatchParam(req *pb_v1.GateWhiteMatchRequest) string { switch { case req.Sn == "" || req.Protocol == 0: return "设备序列号不能为空" case req.CodeVal == "": return "卡号或用户id不能为空" case req.CodeType == 0: return "认证类型不能为空" } return "" } func getWhiteMatchKey(gardenId int64, codeType int32, codeVal string) string { key := fmt.Sprintf("gate_white_%v_%v_%v", gardenId, codeType, codeVal) return key } func setWhiteMatchToRedis(gardenId int64, codeType int32, codeVal string, reply *pb_v1.GateWhiteMatchReply) { key := getWhiteMatchKey(gardenId, codeType, codeVal) bytes, _ := json.Marshal(reply) cache.Redis().SetEx(key, 300, string(bytes)) } func getWhiteMatchFromRedis(gardenId int64, codeType int32, codeVal string) (info *pb_v1.GateWhiteMatchReply) { key := getWhiteMatchKey(gardenId, codeType, codeVal) str, _ := cache.Redis().Get(key) if str == "" { return nil } ret := pb_v1.GateWhiteMatchReply{} json.Unmarshal([]byte(str), &ret) return &ret } func getMatchInfoFromCardDb(gardenId int64, codeVal string, gateInfo *gate_utils.GateCommonInfo) (*pb_v1.GateWhiteMatchReply, error) { ucards := dbmodel.TUserCard{} where := [][2]interface{}{} where = dbmodel.WhereAdd(where, "garden_id", gardenId) where = dbmodel.WhereAdd(where, "card_number", codeVal) err := ucards.Find(database.DB(), where) if err != nil && err != gorm.ErrRecordNotFound { return nil, errors.DataBaseError } if ucards.ID == 0 { return &pb_v1.GateWhiteMatchReply{}, nil } gcards := dbmodel.TGateCard{} where = [][2]interface{}{} where = dbmodel.WhereAdd(where, "device_id", gateInfo.DeviceId) where = dbmodel.WhereAdd(where, "record_id", ucards.ID) err = gcards.Find(database.DB(), where) if err != nil && err != gorm.ErrRecordNotFound { return nil, errors.DataBaseError } if gcards.ID == 0 { return &pb_v1.GateWhiteMatchReply{}, nil } ret := pb_v1.GateWhiteMatchReply{ Status: 1, Name: ucards.Name, HouseName: "", Phone: "", IdNumber: "", Uid: ucards.Uid, CardNumber: "", DeviceName: gateInfo.DeviceName, DeviceId: gateInfo.DeviceId, GardenId: gardenId, } return &ret, nil } func GetMatchInfoFromUserDb(gardenId int64, codeVal string, gateInfo *gate_utils.GateCommonInfo) (*pb_v1.GateWhiteMatchReply, error) { uid, _ := strconv.Atoi(codeVal) if uid == 0 { return nil, status.Error(10003, "uid错误") } mreq := pb_v1.GardenHouseholdListRequest{GardenId: gardenId, Uid: int64(uid), PageSize: -1, Page: -1} mreply, err := pb.Garden.GardenHouseholdList(context.Background(), &mreq) if err != nil { return nil, err } if len(mreply.List) == 0 { return nil, status.Error(10003, "用户不存在") } unitIds := []int64{} m := map[int64]pb_v1.GardenHouseholdItem{} for _, v := range mreply.List { if _, ok := m[v.UnitId]; ok { continue } unitIds = append(unitIds, v.UnitId) m[v.UnitId] = *v } p := dbmodel.TGateUnit{} where := [][2]interface{}{} where = dbmodel.WhereAdd(where, "garden_id", gardenId) where = dbmodel.WhereAdd(where, "device_id", gateInfo.DeviceId) where = dbmodel.WhereAdd(where, "unit_id in", unitIds) err = p.Find(database.DB(), where) if err != nil && err != gorm.ErrRecordNotFound { return nil, errors.DataBaseError } if p.ID == 0 { return &pb_v1.GateWhiteMatchReply{}, nil } ret := pb_v1.GateWhiteMatchReply{ Status: 1, Name: m[p.UnitId].Name, HouseName: m[p.UnitId].HouseName, Phone: m[p.UnitId].Phone, IdNumber: m[p.UnitId].IdNumber, Uid: codeVal, CardNumber: "", DeviceName: gateInfo.DeviceName, DeviceId: gateInfo.DeviceId, GardenId: gardenId, } return &ret, nil } func getMatchInfoFromDb(gardenId int64, codeType int32, codeVal string, gateInfo *gate_utils.GateCommonInfo) (*pb_v1.GateWhiteMatchReply, error) { if codeType == 1 { return GetMatchInfoFromUserDb(gardenId, codeVal, gateInfo) } return getMatchInfoFromCardDb(gardenId, codeVal, gateInfo) } func GateWhiteMatch(ctx context.Context, req *pb_v1.GateWhiteMatchRequest) (reply *pb_v1.GateWhiteMatchReply, err error) { reply = &pb_v1.GateWhiteMatchReply{} // 捕获各个task中的异常并返回给调用者 defer func() { if r := recover(); r != nil { err = fmt.Errorf("%+v", r) e := &status.Status{} if er := json.Unmarshal([]byte(err.Error()), e); er != nil { logger.Error("err", zap.String("system_err", err.Error()), zap.Stack("stacktrace")) } } }() desc := checkGateWhiteMatchParam(req) if desc != "" { reply.Status = 0 return reply, nil } gateInfo, err := gate_utils.GetGateGarden(req.Sn, req.Protocol) if err != nil { return nil, err } matchInfo := getWhiteMatchFromRedis(gateInfo.GardenId, req.CodeType, req.CodeVal) if matchInfo != nil { return matchInfo, nil } matchInfo, err = getMatchInfoFromDb(gateInfo.GardenId, req.CodeType, req.CodeVal, &gateInfo) if err != nil { return nil, err } if matchInfo.DeviceId == 0 { matchInfo.Status = 0 return matchInfo, nil } matchInfo.Status = 1 setWhiteMatchToRedis(gateInfo.GardenId, req.CodeType, req.CodeVal, matchInfo) return matchInfo, nil }