package v1 import ( "context" "crypto/rc4" "encoding/hex" "fmt" "git.getensh.com/common/gopkgs/logger" "git.getensh.com/common/gopkgs/tasker/httptasker" "github.com/gin-gonic/gin" "go.uber.org/zap" "net/http" param_v1 "property-device-gateway/param/v1" "property-device-gateway/parser" "property-device-gateway/pb" pb_v1 "property-device-gateway/pb/v1" "strconv" "strings" "time" ) /* var commandCodeMap = map[int32]string{ 1: "远程开门", 2: "重启设备", 4: "获取设备参数", 5: "设置设备参数", 6: "下发白名单", 7: "清空设备白名单", 8: "清空设备刷卡记录", 9: "扫码显示参数", 10: "查询是否存在白名单", 99: "恢复出厂", } */ const ( SaiboOpenCommand = 1 SaiboRebootCommand = 2 SaiboDownCommand = 6 SaiboQueryCommand = 10 ) const ( OpenCommand = 1 RebootCommand = 2 DownCommand = 3 DelCommand = 4 QueryCommand = 5 UpdatePicCommand = 6 AddPicCommand = 7 ) var LocalCommandToSaiboM = map[int32]int32{ OpenCommand: SaiboOpenCommand, RebootCommand: SaiboRebootCommand, DownCommand: SaiboDownCommand, QueryCommand: SaiboQueryCommand, } var SaiboCommandToLocaolM = map[int32]int32{ SaiboOpenCommand: OpenCommand, SaiboRebootCommand: RebootCommand, SaiboDownCommand: DownCommand, SaiboQueryCommand: QueryCommand, } func Rc4Test() { //miwen := "05F459B27337BE46B7E42584860382A5203DE5853026309693C0ED0ABE5427C212BE338B1DC3E289AAFE66" //miwen,_ := hex.DecodeString("05F459B27337BE46B7E42584860382A5203DE5853026309693C0ED0ABE5427C212BE338B1DC3E289AAFE66") miwen := "[1,123,20180101143618,20240114144618]" dest := make([]byte, len(miwen)) cipher2, _ := rc4.NewCipher([]byte("CB1712345678")) cipher2.XORKeyStream(dest, []byte(miwen)) fmt.Printf("%X\n", dest) } func Rc4Decrypt(encrypt string, key string) string { if len(encrypt) < 4 { return "" } if encrypt[:4] != "CB01" { return "" } miwen, _ := hex.DecodeString(encrypt[4:]) dest := make([]byte, len(miwen)) cipher2, _ := rc4.NewCipher([]byte(key)) cipher2.XORKeyStream(dest, []byte(miwen)) return string(dest) } func checkCode(req *param_v1.CodeGateCheckCodeRequest) (int, int32, string, string, int64) { loc, _ := time.LoadLocation("Local") if req.CodeType != "Q" && req.CodeType != "C" { return 0, 0, "", "", 0 } visitor := int32(2) vname, vphone := "", "" vid := int64(0) if req.CodeType == "Q" { text := Rc4Decrypt(req.CodeVal, parser.Conf.GateKey) if text == "" { if req.IsOnline == "0" { return 1, 0, "", "", 0 } return 0, 0, "", "", 0 } length := len(text) array := strings.Split(text[1:length-1], ",") req.CodeVal = array[0] if len(array) < 4 { return 0, 0, "", "", 0 } subArray := strings.Split(array[0], "-") if len(subArray) > 3 { req.CodeVal = subArray[0] visitor = 1 vphone = subArray[1] vname = subArray[2] vid, _ = strconv.ParseInt(subArray[3], 10, 64) } start, _ := time.ParseInLocation("20060102150405", array[2], loc) end, _ := time.ParseInLocation("20060102150405", array[3], loc) now := time.Now() if now.Unix() < start.Unix() || now.Unix() > end.Unix() { return 0, 0, "", "", 0 } } return 1, visitor, vname, vphone, vid } func addRecord(req *param_v1.CodeGateCheckCodeRequest, mreply *pb_v1.GateWhiteMatchReply, visitor int32, vname string, vphone string) { recordReq := pb_v1.GateRecordAddRequest{ DeviceId: mreply.DeviceId, Location: mreply.Location, Direction: mreply.Direction, HouseholdUser: "", HouseholdIdNumber: "", HouseholdHousename: "", CardNumber: "", CardOwner: "", Online: 1, GardenId: mreply.GardenId, // 1 访客 2 非访客 IsVisitor: visitor, // 开门时间 OpenTime: 0, HouseholdUid: 0, VisitorPhone: vphone, VisitorName: vname, Sn: req.UID, Protocol: GateProtocolSaiboHttpV1, OpenType: 1, } if req.CodeType == "C" { recordReq.OpenType = 2 } if req.IsOnline == "0" { recordReq.Online = 2 } loc, _ := time.LoadLocation("Local") t, _ := time.ParseInLocation("2006-01-02 15:04:05", req.BrushTime, loc) recordReq.OpenTime = t.Unix() if req.CodeType == "Q" { recordReq.HouseholdUid, _ = strconv.ParseInt(mreply.Uid, 10, 64) recordReq.HouseholdUser = mreply.Name recordReq.HouseholdIdNumber = mreply.IdNumber recordReq.HouseholdHousename = mreply.HouseName } else { recordReq.CardNumber = mreply.CardNumber recordReq.CardOwner = mreply.Name } _, _ = pb.Device.GateRecordAdd(context.Background(), &recordReq) } // // @Summary 设备上传数据 // @Description 设备上传数据 // @Tags 二维码门禁 // @Accept json // @Produce json // @Param body body v1.CodeGateCheckCodeBody true " " // @Success 200 {object} v1.CodeGateCheckCodeResponse // @Failure 500 {object} base.HTTPError // @Router /api/CheckCode [post] func (c *Controller) CodeGateCheckCode(ctx *gin.Context) { // 解析参数 req := ¶m_v1.CodeGateCheckCodeRequest{} parseParamTask := func() error { str := ctx.Request.FormValue("paramaters") fmt.Printf("check code:%v\n", str) json.Unmarshal([]byte(str), &req.CodeGateCheckCodeBody) return nil } // 业务处理 handleServiceTask := func() error { // 响应数据 resp := param_v1.CodeGateCheckCodeResponse{} // 解析并检查数据 status, visitor, vname, vphone, vid := checkCode(req) if status == 0 { resp.UID = req.UID resp.Status = 0 ctx.JSON(http.StatusOK, resp) return nil } // 检查白名单 mreq := pb_v1.GateWhiteMatchRequest{ CodeVal: req.CodeVal, CodeType: 1, Sn: req.UID, Protocol: GateProtocolSaiboHttpV1, } if req.CodeType == "C" { mreq.CodeType = 2 } mreply, err := pb.Device.GateWhiteMatch(context.Background(), &mreq) if err != nil { s, _ := json.MarshalToString(req) logger.Error("func", zap.String("call", "pb.Device.GateWhiteMatch"), zap.String("params", s), zap.String("error", err.Error())) resp.UID = req.UID resp.Status = 0 ctx.JSON(http.StatusOK, resp) return nil } // 白名单不匹配 if mreply.Status != 1 { resp.UID = req.UID resp.Status = 0 ctx.JSON(http.StatusOK, resp) return nil } // 检查访客 if visitor == 1 { mreq := pb_v1.GateVisitorCheckRequest{Id: vid, DeviceId: mreply.DeviceId} loc, _ := time.LoadLocation("Local") t, _ := time.ParseInLocation("2006-01-02 15:04:05", req.BrushTime, loc) mreq.OpenTime = t.Unix() _, err = pb.Device.GateVisitorCheck(context.Background(), &mreq) if err != nil { s, _ := json.MarshalToString(req) logger.Error("func", zap.String("call", "pb.Device.GateVisitorCheck"), zap.String("params", s), zap.String("error", err.Error())) resp.UID = req.UID resp.Status = 0 ctx.JSON(http.StatusOK, resp) return nil } } // 开门记录 resp.UID = req.UID resp.Status = int(mreply.Status) addRecord(req, mreply, visitor, vname, vphone) ctx.JSON(http.StatusOK, resp) return nil } // 执行任务 httptasker.Exec(ctx, parseParamTask, handleServiceTask) } // // @Summary 心跳 // @Description 心跳 // @Tags 二维码门禁 // @Accept json // @Produce json // @Param body body v1.CodeGateIsConnectBody true " " // @Success 200 {object} v1.CodeGateIsConnectResponse // @Failure 500 {object} base.HTTPError // @Router /api/IsConnect [post] func (c *Controller) CodeGateIsConnect(ctx *gin.Context) { // 解析参数 req := ¶m_v1.CodeGateIsConnectRequest{} parseParamTask := func() error { str := ctx.Request.FormValue("paramaters") //fmt.Printf("is connect:%v\n", str) json.Unmarshal([]byte(str), &req.CodeGateIsConnectBody) return nil } // 业务处理 handleServiceTask := func() error { // 响应数据 mreq := pb_v1.GateOnlineRequest{Sn: req.UID, Protocol: GateProtocolSaiboHttpV1} _, err := pb.Device.GateOnline(context.Background(), &mreq) if err != nil { s, _ := json.MarshalToString(req) logger.Error("func", zap.String("call", "pb.Device.GateOnline"), zap.String("params", s), zap.String("error", err.Error())) } resp := param_v1.CodeGateIsConnectResponse{} resp.DateTime = time.Now().Format("2006-01-02 15:04:05") ctx.JSON(http.StatusOK, resp) return nil } // 执行任务 httptasker.Exec(ctx, parseParamTask, handleServiceTask) } var TestCount = 0 // // @Summary 轮询是否有命令 // @Description 轮询是否有命令 // @Tags 二维码门禁 // @Accept json // @Produce json // @Param body body v1.CodeGateQueryCmdBody true " " // @Success 200 {object} v1.CodeGateQueryCmdResponse // @Failure 500 {object} base.HTTPError // @Router /api/QueryCmd [post] func (c *Controller) CodeGateQueryCmd(ctx *gin.Context) { // 解析参数 req := ¶m_v1.CodeGateQueryCmdRequest{} parseParamTask := func() error { str := ctx.Request.FormValue("paramaters") //fmt.Printf("qury cmd:%v\n", str) json.Unmarshal([]byte(str), &req.CodeGateQueryCmdBody) return nil } // 业务处理 // 0 无命令; //1 远程开门; //2 重启设备; //4 获取设备参数; //5 设置设备参数; 6 下载白名单; //7 清空本地所有白名单; //8 清空本地所有刷卡记录; //9 扫码显示参数; //10 查询卡号是否存在白名单 //99 恢复出厂; handleServiceTask := func() error { // 响应数据 resp := param_v1.CodeGateQueryCmdResponse{} mreq := pb_v1.GateCommandUseRequest{Sn: req.UID, Protocol: GateProtocolSaiboHttpV1} mreply, err := pb.Device.GateCommandUse(context.Background(), &mreq) if err != nil { s, _ := json.MarshalToString(req) logger.Error("func", zap.String("call", "pb.Device.GateCommandUse"), zap.String("params", s), zap.String("error", err.Error())) resp.CmdID = "0" resp.CmdCode = 0 ctx.JSON(http.StatusOK, resp) return nil } if mreply.CmdCode == 0 { resp.CmdID = "0" resp.CmdCode = 0 ctx.JSON(http.StatusOK, resp) return nil } resp.CmdID = fmt.Sprintf("%d", mreply.Id) resp.CmdCode = int(LocalCommandToSaiboM[mreply.CmdCode]) resp.CmdParams = []map[string]string{} if mreply.CmdParams != "" { json.Unmarshal([]byte(mreply.CmdParams), &resp.CmdParams) } ctx.JSON(http.StatusOK, resp) return nil } // 执行任务 httptasker.Exec(ctx, parseParamTask, handleServiceTask) } // // @Summary 命令执行结果 // @Description 命令执行结果 // @Tags 二维码门禁 // @Accept json // @Produce json // @Param body body v1.CodeGateQueryCmdPostDataBody true " " // @Success 200 {object} v1.CodeGateQueryCmdPostDataResponse // @Failure 500 {object} base.HTTPError // @Router /api/QueryCmdPostData [post] func (c *Controller) CodeGateQueryCmdPostData(ctx *gin.Context) { // 解析参数 req := ¶m_v1.CodeGateQueryCmdPostDataRequest{} content := "" parseParamTask := func() error { str := ctx.Request.FormValue("paramaters") fmt.Printf("qury cmd post data:%v\n", str) json.Unmarshal([]byte(str), &req.CodeGateQueryCmdPostDataBody) content = string(str) return nil } handleServiceTask := func() error { // 响应数据 resp := param_v1.CodeGateQueryCmdPostDataResponse{} resp.CmdStatus = req.CmdStatus id, _ := strconv.ParseInt(req.CmdID, 10, 64) mreq := pb_v1.GateCommandResultRequest{ Id: id, CmdCode: int32(SaiboCommandToLocaolM[int32(req.CmdCode)]), ResultStatus: int32(req.CmdStatus), ResultDesc: "", Sn: req.UID, Protocol: GateProtocolSaiboHttpV1, Content: content, } _, err := pb.Device.GateCommandResult(context.Background(), &mreq) if err != nil { s, _ := json.MarshalToString(req) logger.Error("func", zap.String("call", "pb.Device.GateCommandResult"), zap.String("params", s), zap.String("error", err.Error())) ctx.JSON(http.StatusOK, resp) return nil } ctx.JSON(http.StatusOK, resp) return nil } // 执行任务 httptasker.Exec(ctx, parseParamTask, handleServiceTask) }