package base_api import ( "context" "gd_management/apis" "gd_management/errors" "gd_management/impl/pubsub" "gd_management/rpc_apis" "gd_management/rpc_apis/gd_access_log" "encoding/json" "fmt" "strings" "time" "gd_management/common.in/storage" "gd_management/common.in/utils" "github.com/astaxie/beego/orm" "go.uber.org/zap" ) type UpdateParams struct { RequestParam string ResponseParam string Id int64 MerchantDataApiId int64 ReqList []apis.ManagementBaseApiParam RespList []apis.ManagementBaseApiParam NewReqList []apis.ManagementBaseApiParam NewRespList []apis.ManagementBaseApiParam } func updateBaseApiReqToDBStruct(req *apis.ManagementUpdateBaseApiReq) (*apis.TGdApi, string, string, string, string, error) { paramPreProcess(&req.BaseApiInfo) reqParam, err := json.Marshal(req.BaseApiInfo.RequestParam) if err != nil { return nil, "", "", "", "", err } resParam, err := json.Marshal(req.BaseApiInfo.ResponseParam) if err != nil { return nil, "", "", "", "", err } errids := "" for _, id := range req.BaseApiInfo.ErrorCode { if errids == "" { errids = fmt.Sprintf("%d", id) } else { errids = errids + "," + fmt.Sprintf("%d", id) } } now := time.Now().Format("2006-01-02 15:04:05") ret := apis.TGdApi{} err = orm.NewOrm().QueryTable("t_gd_api").Filter("id", req.ApiId).One(&ret) if err != nil { return &ret, "", "", "", "", errors.DataBaseError } oldRouter := ret.Router oldMethod := ret.Method oldName := ret.Name ret.Id = req.ApiId ret.ApiType = req.BaseApiInfo.Type ret.Method = strings.ToUpper(req.BaseApiInfo.Method) ret.Router = req.BaseApiInfo.Router ret.Name = req.BaseApiInfo.Name ret.ErrorCodeIds = errids ret.RequestParam = string(reqParam) ret.ResponseParam = string(resParam) ret.UpdateTime = now ret.Comment = req.BaseApiInfo.Comment if strings.HasPrefix(ret.Router, "/") == false { ret.Router = fmt.Sprintf("/%s", ret.Router) } return &ret, oldName, ret.Name, oldRouter, oldMethod, nil } func getNewParamList(dst []apis.ManagementBaseApiParam, src []apis.ManagementBaseApiParam) (ret []apis.ManagementBaseApiParam) { for _, s := range src { exist := false for _, d := range dst { if s.Name == d.Name { exist = true item := d if s.Type != d.Type { item.Type = s.Type } if s.Mean != d.Mean { item.Mean = s.Mean } if s.Example != d.Example { item.Example = s.Example } item.Child = getNewParamList(d.Child, s.Child) ret = append(ret, item) break } } if exist == false { s.Selected = false ret = append(ret, s) } } return ret } func getUpdateParams(reqList []apis.ManagementBaseApiParam, respList []apis.ManagementBaseApiParam, updateParams []UpdateParams) []UpdateParams { for i, v := range updateParams { json.Unmarshal([]byte(v.RequestParam), &updateParams[i].ReqList) json.Unmarshal([]byte(v.ResponseParam), &updateParams[i].RespList) updateParams[i].NewReqList = getNewParamList(updateParams[i].ReqList, reqList) updateParams[i].NewRespList = getNewParamList(updateParams[i].RespList, respList) bytes, _ := json.Marshal(updateParams[i].NewReqList) updateParams[i].RequestParam = string(bytes) bytes, _ = json.Marshal(updateParams[i].NewRespList) updateParams[i].ResponseParam = string(bytes) } return updateParams } func updateChildDataApi(o orm.Ormer, req *apis.ManagementUpdateBaseApiReq, timeNow string) error { var updateParams []UpdateParams _, err := o.Raw("select request_param ,response_param ,id from t_gd_child_data_api where api_id = ?", req.ApiId).QueryRows(&updateParams) if err != nil && err != orm.ErrNoRows { return errors.DataBaseError } updateParams = getUpdateParams(req.BaseApiInfo.RequestParam, req.BaseApiInfo.ResponseParam, updateParams) for _, v := range updateParams { _, err := o.Raw("update t_gd_child_data_api set request_param = ? ,response_param = ?,update_time = ? where id = ?", v.RequestParam, v.ResponseParam, timeNow, v.Id).Exec() if err != nil { fmt.Printf("database err:%v\n", err) return errors.DataBaseError } } return nil } func updateMerchantChildDataApi(o orm.Ormer, req *apis.ManagementUpdateBaseApiReq, timeNow string) ([]UpdateParams, error) { var updateParams []UpdateParams _, err := o.Raw("select request_param ,response_param ,id, merchant_data_api_id from t_gd_merchant_child_data_api where api_id = ?", req.ApiId).QueryRows(&updateParams) if err != nil && err != orm.ErrNoRows { return updateParams, errors.DataBaseError } updateParams = getUpdateParams(req.BaseApiInfo.RequestParam, req.BaseApiInfo.ResponseParam, updateParams) for _, v := range updateParams { _, err := o.Raw("update t_gd_merchant_child_data_api set request_param = ? ,response_param = ?,update_time = ? where id = ?", v.RequestParam, v.ResponseParam, timeNow, v.Id).Exec() if err != nil { fmt.Printf("database err:%v\n", err) return updateParams, errors.DataBaseError } } return updateParams, nil } func updateBaseApi(req *apis.ManagementUpdateBaseApiReq) error { dbstruct, oldName, newName, oldRouter, oldMethod, err := updateBaseApiReqToDBStruct(req) if err != nil { return errors.ArgsError } task := func(o orm.Ormer) error { requestParam := "" responseParam := "" o.Raw("select request_param , response_param from t_gd_api where id =?", req.ApiId).QueryRow(&requestParam, &responseParam) _, err = o.Update(dbstruct, "name", "method", "api_type", "router", "error_code_ids", "request_param", "response_param", "comment", "update_time") if err != nil { fmt.Printf("database err:%v\n", err) return errors.DataBaseError } updateParams := []UpdateParams{} if requestParam != dbstruct.RequestParam || responseParam != dbstruct.ResponseParam { err := updateChildDataApi(o, req, dbstruct.UpdateTime) if err != nil { return errors.DataBaseError } updateParams, err = updateMerchantChildDataApi(o, req, dbstruct.UpdateTime) if err != nil { return errors.DataBaseError } } if oldName != newName && newName != "" { if err := pubsub.PublishNameNotify("api_id", dbstruct.Id, 0); err != nil { return err } dreq := gd_access_log.LogUpdateApiNameReq{ Type: 0, Name: newName, Id: dbstruct.Id, } go func() error { _, err := rpc_apis.AccessLog.LogUpdateApiName(context.Background(), &dreq) return err }() } err = utils.RedisSet("t_gd_api", dbstruct.Method+"-"+dbstruct.Router, dbstruct) if err != nil { return errors.DataBaseError } if err := pubsub.PublishApiNotify(req.ApiId, oldRouter, oldMethod); err != nil { return err } for _, p := range updateParams { if err := pubsub.PublishMerchantApiNotify(p.MerchantDataApiId, 0, 0, 0); err != nil { return err } } return nil } tasks := []storage.DbaTasker{} tasks = append(tasks, storage.GenerateDbaTask(task)) storage.ExecTrans(tasks...) return nil } func ManagementUpdateBaseApi(ctx context.Context, req *apis.ManagementUpdateBaseApiReq, reply *apis.ManagementUpdateBaseApiReply) (err error) { err = updateBaseApi(req) if err != nil { l.Error("func", zap.String("call", "ManagementUpdateBaseApi"), zap.String("args", utils.MarshalJsonString(req)), zap.String("error", err.Error())) } reply.ApiId = req.ApiId l.Debug(utils.MarshalJsonString(req, reply)) return }