package utils import ( "errors" "log" "sfbase/global" "sfbase/utils" "sfis/db" "sfis/model" "gorm.io/gorm" ) /** 扣产品剩余量 */ func costByLeftNum(getData func() ([]map[string]interface{}, int, error), appID string, productID int, userProduct *model.UserProduct, product *model.Product, param, ip string) ([]map[string]interface{}, error) { productType := product.ProductType datas := []map[string]interface{}{} var err error beforeJudge := before(productType, userProduct) if beforeJudge { data, statusCode, _ := execute(getData, appID, productID) err = after(productType, len(data), userProduct, statusCode, param, ip) if err == nil && data != nil && len(data) > 0 { datas = data } else { if err != nil { global.Logger.Error("数据库操作失败", getUserProductError(appID, productID, err)...) } else { global.Logger.Info("无数据", getUserProductError(appID, productID, err)...) } } } else { err = errors.New("剩余量不足") } return datas, err } /** 用户产品剩余量|账户余额判断 */ func before(productType int, userProduct *model.UserProduct) bool { switch productType { case 0: //按次扣费-判断left_num if userProduct.LeftNum == 0 { //response.FailWithDetailed(response.LeftNumEmpty, nil, "余额不足", context) return false } case 1: //按条扣费-判断单次调用的limit if userProduct.LeftNum < userProduct.DataNumLimitOneTimes { //response.FailWithDetailed(response.LeftNumEmpty, nil, "剩余数据量小于该产品每次返回数据量,可能造成数据量不准确", context) return false } } return true } /** 执行接口查询 */ func execute(getData func() ([]map[string]interface{}, int, error), appID string, productID int) ([]map[string]interface{}, int, error) { data, statusCode, err := getData() if err != nil { global.Logger.Error("调用数据出错:", getUserProductError(appID, productID, err)...) return nil, -1, err } dataLen := len(data) global.Logger.Info("调用成功:", getUserProductInfo(appID, productID, "数据长度", dataLen)...) return data, statusCode, nil } func after(productType int, dataLen int, userProduct *model.UserProduct, statusCode int, param, ip string) error { appID := userProduct.AppID productID := userProduct.ProductID userProductID := userProduct.ID var errs error switch productType { case 0: //按次扣费-(每调一次剩余量-1) errs = db.GetSFISDB().Transaction(func(tx *gorm.DB) error { orderBefore := userProduct.LeftNum orderAfter := userProduct.LeftNum - 1 //扣费 err := tx.Exec("update user_product set left_num = IF(`left_num`<1, 0, `left_num`-1) WHERE `app_id` = ? and product_id=?", appID, productID).Error if err != nil { log.Printf("appID:[%s],productID:[%d] execute cost left_num-1 error:[%v]", appID, productID, err) tx.Rollback() return err } //生调用记录 err = tx.Exec("insert into user_call_record (app_id,user_product_id,status,ip,param) values (?,?,?,?,?)", appID, userProductID, statusCode, ip, param).Error if err != nil { log.Printf("appID:[%s],productID:[%d] execute insert into user_call_record error:[%v]", appID, productID, err) tx.Rollback() return err } //生订单 orderCode := utils.GenerateSimpleToken() err = tx.Exec("insert into interface_order (order_code,app_id,user_product_id,`before`,`after`,cost_model,trade_num) values (?,?,?,?,?,?,?)", orderCode, appID, userProductID, orderBefore, orderAfter, 0, 1).Error if err != nil { log.Printf("appID:[%s],productID:[%d] execute insert into interface_order error:[%v]", appID, productID, err) tx.Rollback() return err } //存历史数据 return nil }) case 1: //按条扣费-(每调一次剩余量-len(getDataList)) errs = db.GetSFISDB().Transaction(func(tx *gorm.DB) error { orderBefore := userProduct.LeftNum orderAfter := userProduct.LeftNum - dataLen //扣费 tx.Exec("update user_product set left_num = IF(`left_num`<1, 0, `left_num`-?) WHERE `app_id` = ? and product_id=?", dataLen, appID, productID) //生调用记录 err := tx.Exec("insert into user_call_record (app_id,user_product_id,status,ip,param) values (?,?,?,?,?)", appID, userProductID, statusCode, ip, param).Error if err != nil { log.Printf("appID:[%s],productID:[%d] execute insert into user_call_record error:[%v]", appID, productID, err) tx.Rollback() return err } //生订单 orderCode := utils.GenerateSimpleToken() err = tx.Exec("insert into interface_order (order_code,app_id,user_product_id,`before`,`after`,cost_model,trade_num) values (?,?,?,?,?,?,?)", orderCode, appID, userProductID, orderBefore, orderAfter, 0, 1).Error if err != nil { log.Printf("appID:[%s],productID:[%d] execute insert into interface_order error:[%v]", appID, productID, err) tx.Rollback() return err } //存历史数据 return nil }) } return errs }