package utils import ( // "context" "fmt" "log" "sfbase/global" "sfbase/redis" "sfis/db" "sfis/lock" "sfis/model" "sfis/model/response" "strings" "time" "github.com/gin-gonic/gin" "go.uber.org/zap" ) func Check(appID string, productID int, c *gin.Context, getData func() ([]map[string]interface{}, int, error), param, ip string) { lock.MainLock.Lock() userLock := lock.UserLockMap[appID] lock.MainLock.Unlock() var err error datas := []map[string]interface{}{} orderCode := "" errStr := "" /** 第二步:用户接口产品校验-加锁处理 */ //2.1 取用户接口状态校验-可加锁也可不加锁 这个没有太严谨 //userLock.Lock() userProduct := &model.UserProduct{} db.GetSFISDB().First(userProduct, &model.UserProduct{AppID: appID, ProductID: productID}) //userLock.Unlock() if userProduct.ID == 0 { response.FailWithDetailed(response.InterfaceDeleted, nil, "该用户接口未购买", c) return } else if userProduct.InterfaceStatus != 0 { response.FailWithDetailed(response.InterfaceDeleted, nil, "该用户接口暂不提供服务", c) return } //2.2 取用户(产品余量|钱包账户余额)校验-必须加锁 costModel := userProduct.CostModel //扣费模式 0扣余量,1-扣余额 product := GetProductByID(productID) userLock.Lock() log.Println(param + "锁住......") // // ctx, _ := context.WithTimeout(c, 20*time.Second) // go func() { // var i = 0 // for { // select { // case <-ctx.Done(): // userLock.Unlock() // return // case <-time.After(time.Second * time.Duration(2)): // i++ // if i == 10 { // userLock.Unlock() // return // } // continue // } // } // }() // time.Sleep(time.Second * time.Duration(25)) // db.GetSFISDB().First(userProduct, &model.UserProduct{AppID: appID, ProductID: productID}) // costModel = 0 switch costModel { case 0: //按剩余量扣费 datas, orderCode, err, errStr = costByLeftNum(getData, appID, productID, userProduct, product, param, ip) case 1: //按账户钱包余额扣费 datas, orderCode, err, errStr = costByAccountBalance(getData, appID, productID, userProduct, product, param, ip) case 2: //优先扣剩余量,剩余量为0,扣钱包余额 } userLock.Unlock() log.Println(param + "解锁......") if err == nil { db.GetQyfw().Save("user_data", map[string]interface{}{ "app_id": appID, "result_num": len(datas), "result_content": datas, "order_code": orderCode, "status": 200, "user_product_id": userProduct.ID, "create_at": time.Now().Unix(), }) limittodaykey := fmt.Sprintf("limittoday_%d_%d_%s", time.Now().Day(), userProduct.ProductID, userProduct.AppID) redis.Incr("limit", limittodaykey) response.FailWithDetailed(response.SUCCESS, datas, "OK", c) } else { if strings.Contains(errStr, "不足") { response.FailWithDetailed(response.LeftNumEmpty, nil, errStr, c) } else { global.Logger.Error("数据库操作失败", zap.Any("error:", err)) response.FailWithDetailed(response.QueryError, nil, "内部错误", c) } } }