package ctrl_v1 import ( "context" "encoding/json" "gd_gateway/apis" "gd_gateway/common.in/config" "gd_gateway/common.in/httper" "gd_gateway/common.in/jsonrpc2" "gd_gateway/common.in/task" "gd_gateway/common.in/utils" "gd_gateway/errors" "gd_gateway/params/param_base" "gd_gateway/params/param_v1_0" "gd_gateway/rpc_apis_v1" dutils "gd_gateway/utils" "github.com/astaxie/beego" beegoctx "github.com/astaxie/beego/context" "go.uber.org/zap" "strings" "time" ) // Operations about vehicle type CenterController struct { metadata interface{} // 中继元数据 beego.Controller LogID string } func (u *CenterController) handleGetCheckImpl(ctx context.Context, uctx *beegoctx.Context, req *param_v1_0.ParamQuery, startTime uint64, appkey string) (cReply apis.ManagementCheckApiReply, err error) { // 透传通用信息 cReq := apis.ManagementCheckApiReq{ Method: u.Ctx.Request.Method, Router: u.Ctx.Request.URL.Path, Ip: u.Ctx.Input.IP(), RequestParam: []byte(req.Data), OriginRequestParam: req.Data, } // 填写头部信息 cReq.Header = make(map[string]string, 0) if appkey != ""{ cReq.Header["app_key"] = appkey }else{ cReq.Header["app_key"] = req.Appkey } cReq.Header["ts"] = req.Timestamp cReq.Header["encrypt_type"] = req.EncryptType cReq.Header["sign"] = req.Sign //cReq.Header["is_sign"] = req.IsSign cReq.Header["replace_app_key"] = req.ReplaceAppKey // 验证接口权限 cReply, err = rpc_apis_v1.AuthCheck.ManagementCheckApi(ctx, &cReq) //fmt.Printf("auth_check:%+v\n, err:%+v\n", cReply, err) // 生成流水号 orderNo := utils.GetResponseOrderNo(cReply.MerchantApiInfo.ResponseParamConf) uctx.Input.Context.Request.Header.Add("order_no", orderNo) if err != nil || cReply.ErrCode != 0 { // 若不为 0,则覆盖 err 错误信息 if cReply.ErrCode != 0 { err = jsonrpc2.NewJsonError(cReply.ErrCode, cReply.ErrMsg) } //err = errors.ErrorTransform(err) // 写入失败日志 dutils.WriteInvalidAccessLog( ctx, u.Ctx.Input.IP(), utils.MarshalJsonString(cReq), cReply.MerchantApiInfo.MerchantId, cReply.MerchantApiInfo.BaseApiId, int64(startTime), err) if cReply.MerchantApiInfo.MerchantDataApiId > 0 && (cReply.ErrCode == 1102 || cReply.ErrCode == 1103 || cReply.ErrCode == 1020) { accessLog := dutils.NewAccessLogNew(req.Data, false, []apis.ThirdpartLogWrite{}, u.Ctx.Input.IP(), &cReply.MerchantApiInfo) accessLog.OrderNo = orderNo dutils.WriteAccessLog( ctx, accessLog, startTime, cReply.MerchantApiInfo.MerchantChildApiId, err) } if cReply.ErrCode == 1102{ err = errors.BadParaFormat } } return } // @Title query vehicle info // @Description 查询车辆相关信息 // @Param appkey header string false "appkey" // @Param token header string false "token" // @Param timestamp header string false "时间戳" // @Param sign header string false "签名" // @Param code path string true "code" // @Success 200 {object} params.param_v1_0.CommonResponse "响应信息" // @Failure 500 服务器错误 // @router /query/:code [get] func (u *CenterController) Vehicle() { startTime := uint64(time.Now().UnixNano()) req := ¶m_v1_0.ParamQuery{} cReply := apis.ManagementCheckApiReply{} ctx := utils.NewContextFromBeegoCtx(u.Ctx) getParamsTask := func() error { httper.FillRequireParams(u.Ctx, req, u.LogID) if req.Sign == "" && req.Token == ""{ return jsonrpc2.NewJsonError(1103, "token/签名为空") } if req.Sign != ""{ if req.Timestamp == "" { return jsonrpc2.NewJsonError(1103, "时间搓为空") } if req.Appkey == ""{ return jsonrpc2.NewJsonError(1103, "app key 为空") } } return nil } // 验证签名,访问次数等 handleCheckTask := func() error { var err error var username string if req.Token != ""{ _, username, err = utils.ParseToken(req.Token) if err != nil { return err } } queryAll := u.Ctx.Input.Context.Request.URL.Query() m := map[string]string{} for k, v := range queryAll { if len(v) == 0 { m[k] = "" continue } m[k] = v[0] } if len(m) == 0 { return jsonrpc2.NewJsonError(1103, "参数为空") } queryAllByte, err := json.Marshal(m) req.Data = string(queryAllByte) req.EncryptType = strings.ToUpper(req.EncryptType) cReply, err = u.handleGetCheckImpl(ctx, u.Ctx, req, startTime, username) return err } // 处理 handleDataTask := func() error { orderNo := u.Ctx.Input.Context.Request.Header.Get("order_no") resp := param_v1_0.CommonResponse{ SimpleResp: param_base.SimpleResp{ Code: 0, Msg: "成功", }, OrderNo: orderNo, } // 只取勾选字段 params, _ := utils.GetRequestParamNew( cReply.MerchantApiInfo, cReply.MerchantApiInfo.DecryptParam) // rpc 调用参数 vReq := apis.CommonReq{} if err := json.Unmarshal(params, &vReq.Data); err != nil { } dutils.FillMerchantApiInfo(&vReq.MerchantApiInfo, &cReply.MerchantApiInfo) result := NewResult(int64(startTime), cReply.MerchantApiInfo.MinimalTimeConsuming) go func(result *Result) { code := u.Ctx.Input.Param(":code") vReq.Code = code reply, err := rpc_apis_v1.Vehicle.Query(ctx, &vReq) accessLog := dutils.NewAccessLogNew(req.Data, reply.IsReuse, reply.LReq, u.Ctx.Input.IP(), &cReply.MerchantApiInfo) accessLog.OrderNo = resp.OrderNo if err != nil { l.Error("rpc", zap.String("call", code), zap.String("args", utils.MarshalJsonString(req)), zap.String("error", err.Error())) } else { if reply.ErrCode == 0 { accessLog.RawResponseParams, _ = utils.GetRawResponseParam(cReply.MerchantApiInfo, &reply.Data) accessLog.ResponseParams, err = utils.GetResponseParam(cReply.MerchantApiInfo, &reply.Data,req.EncryptType) if err == nil { result.Data = accessLog.ResponseParams } } else { err = jsonrpc2.NewJsonError(reply.ErrCode, reply.ErrMsg) } } var respErr error // 定时任务已经返回 if CheckTimeLock(result) { respErr = errors.NoRecord err = errors.ApiTimeOut } else { if cReply.MerchantApiInfo.IsRawErrorCode { respErr = errors.ErrorTransform(err) } else { respErr = errors.ErrorToNorecord(err) } result.Chan <- respErr } // 写日志并计数 dutils.WriteAccessLogAndCountCode(ctx, accessLog, startTime, cReply.MerchantApiInfo, err, respErr) }(&result) data, err := GetResult(int64(cReply.MerchantApiInfo.Timeout), &result) dutils.HttpStateCodeReturn(u.Ctx, cReply.MerchantApiInfo, err) if err != nil { return err } else { if req.EncryptType == ""{ m := map[string]interface{}{} if data!= ""{ json.Unmarshal([]byte(data), &m) } resp.Data = m } else { resp.Data = data } httper.JSON(u.Ctx, resp, u.LogID) return nil } } // 执行以上定义的任务 task.Do(&task.PanicRecover{ Ctx: u.Ctx, LogID: u.LogID}, u.Ctx, getParamsTask, handleCheckTask, handleDataTask, ) } // @Title query info // @Description 查询相关信息 // @Param appkey header string false "appkey" // @Param token header string false "token" // @Param timestamp header string false "时间戳" // @Param sign header string false "签名" // @Param code path string true "code" // @Success 200 {object} params.param_v1_0.CommonResponse "响应信息" // @Failure 500 服务器错误 // @router /service/:code [get] func (u *CenterController) Service() { startTime := uint64(time.Now().UnixNano()) req := ¶m_v1_0.ParamQuery{} cReply := apis.ManagementCheckApiReply{} ctx := utils.NewContextFromBeegoCtx(u.Ctx) getParamsTask := func() error { httper.FillRequireParams(u.Ctx, req, u.LogID) if req.Sign == "" && req.Token == ""{ return jsonrpc2.NewJsonError(1103, "token/签名为空") } if req.Sign != ""{ if req.Timestamp == "" { return jsonrpc2.NewJsonError(1103, "时间搓为空") } if req.Appkey == ""{ return jsonrpc2.NewJsonError(1103, "app key 为空") } } return nil } // 验证签名,访问次数等 handleCheckTask := func() error { var err error var username string if req.Token != ""{ _, username, err = utils.ParseToken(req.Token) if err != nil { return err } } queryAll := u.Ctx.Input.Context.Request.URL.Query() m := map[string]string{} for k, v := range queryAll { if len(v) == 0 { m[k] = "" continue } m[k] = v[0] } if len(m) == 0 { return jsonrpc2.NewJsonError(1103, "参数为空") } queryAllByte, err := json.Marshal(m) req.Data = string(queryAllByte) req.EncryptType = strings.ToUpper(req.EncryptType) cReply, err = u.handleGetCheckImpl(ctx, u.Ctx, req, startTime, username) return err } // 处理 handleDataTask := func() error { orderNo := u.Ctx.Input.Context.Request.Header.Get("order_no") resp := param_v1_0.CommonResponse{ SimpleResp: param_base.SimpleResp{ Code: 0, Msg: "成功", }, OrderNo: orderNo, } // 只取勾选字段 params, _ := utils.GetRequestParamNew( cReply.MerchantApiInfo, cReply.MerchantApiInfo.DecryptParam) // rpc 调用参数 vReq := apis.CommonReq{} if err := json.Unmarshal(params, &vReq.Data); err != nil { } dutils.FillMerchantApiInfo(&vReq.MerchantApiInfo, &cReply.MerchantApiInfo) result := NewResult(int64(startTime), cReply.MerchantApiInfo.MinimalTimeConsuming) go func(result *Result) { code := u.Ctx.Input.Param(":code") vReq.Code = code reply, err := rpc_apis_v1.Service.Query(ctx, &vReq) accessLog := dutils.NewAccessLogNew(req.Data, reply.IsReuse, reply.LReq, u.Ctx.Input.IP(), &cReply.MerchantApiInfo) accessLog.OrderNo = resp.OrderNo if err != nil { l.Error("rpc", zap.String("call", code), zap.String("args", utils.MarshalJsonString(req)), zap.String("error", err.Error())) } else { if reply.ErrCode == 0 { accessLog.RawResponseParams, _ = utils.GetRawResponseParam(cReply.MerchantApiInfo, &reply.Data) accessLog.ResponseParams, err = utils.GetResponseParam(cReply.MerchantApiInfo, &reply.Data,req.EncryptType) if err == nil { result.Data = accessLog.ResponseParams } } else { err = jsonrpc2.NewJsonError(reply.ErrCode, reply.ErrMsg) } } var respErr error // 定时任务已经返回 if CheckTimeLock(result) { respErr = errors.NoRecord err = errors.ApiTimeOut } else { if cReply.MerchantApiInfo.IsRawErrorCode { respErr = errors.ErrorTransformRaw(err) } else { respErr = errors.ErrorTransformRaw(err) } result.Chan <- respErr } // 写日志并计数 dutils.WriteAccessLogAndCountCode(ctx, accessLog, startTime, cReply.MerchantApiInfo, err, respErr) }(&result) data, err := GetResult(int64(cReply.MerchantApiInfo.Timeout), &result) dutils.HttpStateCodeReturn(u.Ctx, cReply.MerchantApiInfo, err) if err != nil { return err } else { if req.EncryptType == ""{ m := map[string]interface{}{} if data!= ""{ json.Unmarshal([]byte(data), &m) } resp.Data = m } else { resp.Data = data } httper.JSON(u.Ctx, resp, u.LogID) return nil } } // 执行以上定义的任务 task.Do(&task.PanicRecover{ Ctx: u.Ctx, LogID: u.LogID}, u.Ctx, getParamsTask, handleCheckTask, handleDataTask, ) } // @Title query app login // @Description 获取token // @Param user query string true "用户名" // @Param password query string true "密码" // @Success 200 {object} params.param_v1_0.VehicleLoginResponse "响应信息" // @Failure 500 服务器错误 // @router /token [get] func (u *CenterController) VehicleLogin() { req := ¶m_v1_0.VehicleLoginRequest{} ctx := utils.NewContextFromBeegoCtx(u.Ctx) getParamsTask := func() error { httper.FillRequireParams(u.Ctx, req, u.LogID) return nil } // 处理 handleDataTask := func() error { mReq := apis.MerchantAppLoginReq{User: req.User, Password: req.Password} reply, err := rpc_apis_v1.AuthCheck.MerchantAppLogin(ctx, &mReq) if err != nil { l.Error("rpc", zap.String("call", "rpc_apis_v1.AuthCheck.MerchantAppLogin"), zap.String("args", utils.MarshalJsonString(req)), zap.String("error", err.Error())) return err } token, err := utils.ProductToken(reply.MerchantId, req.User) if err != nil { return errors.LoginTokenFail } expired, _ := config.Conf.Cgi.GdGateway.TokenExpired.Int64() resp := param_v1_0.VehicleLoginResponse{Token: token,Expire:expired} resp.Msg = "成功" httper.JSON(u.Ctx, resp, u.LogID) return nil } // 执行以上定义的任务 task.Do(&task.PanicRecover{ Ctx: u.Ctx, LogID: u.LogID}, u.Ctx, getParamsTask, handleDataTask, ) }