package utils import ( "errors" "log" "sfbase/global" "sfbase/utils" "sfis/db" "sfis/model" "time" "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{}, string, error, string) { productType := product.ProductType datas := []map[string]interface{}{} var err error errStr := "" orderCode := "" beforeJudge := before(productType, userProduct) if beforeJudge { data, statusCode, errs := execute(getData, appID, productID) if errs == nil { datas = data if len(datas) == 0 { global.Logger.Info("无数据", getUserProductError(appID, productID, err)...) } orderCode, err = after(productType, len(data), userProduct, statusCode, param, ip) if err != nil { errStr = "内部错误" global.Logger.Error("数据库操作失败", getUserProductError(appID, productID, err)...) } } else { errStr = "查询错误" global.Logger.Error("查询错误", getUserProductError(appID, productID, err)...) } } else { errStr = "剩余量不足" err = errors.New("剩余量不足") } return datas, orderCode, err, errStr } /** 用户产品剩余量|账户余额判断 */ 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) (string, error) { appID := userProduct.AppID productID := userProduct.ProductID userProductID := userProduct.ID var errs error orderCode := utils.CreateOrderCode() switch productType { case 0: //按次扣费-(每调一次剩余量-1) errs = db.GetSFISDB().Transaction(func(tx *gorm.DB) error { orderBefore := userProduct.LeftNum orderAfter := userProduct.LeftNum - 1 nowStr := time.Now().Local().Format("2006-01-02 15:04:05") //扣费 err := tx.Exec("update user_product set left_num = IF(`left_num`<1, 0, `left_num`-1),update_at = ? WHERE `app_id` = ? and product_id=?", nowStr, 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,product_id,user_product_id,status,ip,param,order_code,create_at) values (?,?,?,?,?,?,?,?)", appID, productID, userProductID, statusCode, ip, param, orderCode, nowStr).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 } //生订单 err = tx.Exec("insert into interface_order (order_code,app_id,product_id,user_product_id,`before`,`after`,cost_model,trade_num,create_at) values (?,?,?,?,?,?,?,?,?)", orderCode, appID, productID, userProductID, orderBefore, orderAfter, 0, 1, nowStr).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 nowStr := time.Now().Local().Format("2006-01-02 15:04:05") //扣费 err := tx.Exec("update user_product set left_num = IF(`left_num`<1, 0, `left_num`-?),update_at = ? WHERE `app_id` = ? and product_id=?", dataLen, nowStr, appID, productID).Error if err != nil { log.Printf("appID:[%s],productID:[%d] execute cost money error:[%v]", appID, productID, err) tx.Rollback() return err } //生调用记录 err = tx.Exec("insert into user_call_record (app_id,product_id,user_product_id,status,ip,param,order_code,create_at) values (?,?,?,?,?,?,?,?)", appID, productID, userProductID, statusCode, ip, param, orderCode, nowStr).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 } //生订单 err = tx.Exec("insert into interface_order (order_code,app_id,product_id,user_product_id,`before`,`after`,cost_model,trade_num,create_at) values (?,?,?,?,?,?,?,?,?)", orderCode, appID, productID, userProductID, orderBefore, orderAfter, 0, dataLen, nowStr).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 orderCode, errs }