xuzhiheng hace 4 años
padre
commit
4aa92df252

+ 3 - 0
api/v1/projects.go

@@ -4,6 +4,7 @@ import (
 	"encoding/json"
 	"sfbase/global"
 	"sfis/middleware"
+	"sfis/model/response"
 	"sfis/service"
 	"sfis/utils"
 
@@ -44,6 +45,8 @@ func getProjectsList(c *gin.Context) {
 		utils.Check(appID, productID, c, func() ([]map[string]interface{}, int, error) {
 			return service.ProjectListData(productID, appID, projectName, winner, bidTime, false)
 		}, param, requestIP)
+	} else {
+		response.FailWithDetailed(response.ParamError, nil, "参数错误", c)
 	}
 }
 

+ 1 - 1
lock/interface.go

@@ -51,7 +51,7 @@ func (l *LeftNumCost) After() {
 func (a *AccountBalanceCost) Deduction() {
 
 }
-func (a *AccountBalanceCost) Before() bool {
+func (a *AccountBalanceCost) Before() {
 
 }
 func (a *AccountBalanceCost) After() {

+ 3 - 2
lock/lock.go

@@ -5,8 +5,9 @@ import (
 )
 
 var (
-	UserLockMap = map[string]*sync.Mutex{}
-	MainLock    = sync.Mutex{}
+	UserLockMap   = map[string]*sync.Mutex{}
+	MainLock      = sync.Mutex{}
+	OrderCodeLock = sync.Mutex{}
 )
 
 func InitUserLock(appID string) {

+ 15 - 12
model/response/response.go

@@ -8,16 +8,16 @@ import (
 
 const (
 	ERROR   int = -1
-	SUCCESS int = 0
+	SUCCESS int = 1000
 	//服务级错误码
-	EmptyResult                  int = 201 //查询无结果
-	ParamError                   int = 202 //参数错误
-	ParamEmpty                       = 203 //参数为空
-	ParamLenInValid              int = 204 //参数长度小于4
-	Waiting                      int = 205 //等待处理中
-	MoreThanQueryDataNumberLimit int = 206 //请求数据的条数超过上限
-	LeftNumEmpty                     = 207 //余额不足
-	QueryError                   int = 299 //系统查询异常,请联系客服
+	EmptyResult                  int = 201  //查询无结果
+	ParamError                   int = 4001 //参数错误
+	ParamEmpty                       = 203  //参数为空
+	ParamLenInValid              int = 204  //参数长度小于4
+	Waiting                      int = 205  //等待处理中
+	MoreThanQueryDataNumberLimit int = 206  //请求数据的条数超过上限
+	LeftNumEmpty                     = 4003 //余额不足
+	QueryError                   int = 4004 //系统查询异常,请联系客服
 
 	//系统级错误码
 	InValidKey    = 101 //当前KEY无效
@@ -27,14 +27,17 @@ const (
 	TokenExpired  = 107 //身份验证已过期
 
 	//105非法请求过多,请联系管理员
-	IpInvalid                       = 108 //被禁止的IP
-	MoreThanEveryDayQueryTimesLimit = 109 //请求超过每日系统限制
+	IpInvalid                       = 4005 //被禁止的IP
+	MoreThanEveryDayQueryTimesLimit = 109  //请求超过每日系统限制
 	//108当前相同查询连续出错,请等2小时后重试
 	InterfaceRightInvalid           = 110 //接口权限未开通
 	InterfaceExpired                = 111 //您的账号剩余使用量已过期
 	InterfaceDeleted                = 112 //接口已停用,请联系管理员
 	MoreThanEveryDayDataNumberLimit = 113 //请求超过每日调用总量限制
 	OtherError                      = 199 //系统未知错误,请联系技术客服
+	//
+	SignError   = 4000 //签名错误
+	SignExpired = 4002 //签名过期
 )
 
 type Response struct {
@@ -93,6 +96,6 @@ func FailWithMessage(message string, c *gin.Context) {
 	Result(ERROR, map[string]interface{}{}, message, c)
 }
 
-func FailWithDetailed(code int, data interface{}, message string, c *gin.Context) {
+func FailWithDetailed(code int, data []map[string]interface{}, message string, c *gin.Context) {
 	Result(code, data, message, c)
 }

+ 36 - 9
utils/api_util.go

@@ -1,25 +1,28 @@
 package utils
 
 import (
+	"context"
 	"log"
 	"sfbase/global"
 	"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, context *gin.Context, getData func() ([]map[string]interface{}, int, error), param, ip string) {
+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 := ""
 	/**
 	第二步:用户接口产品校验-加锁处理
 	*/
@@ -29,10 +32,10 @@ func Check(appID string, productID int, context *gin.Context, getData func() ([]
 	db.GetSFISDB().First(userProduct, &model.UserProduct{AppID: appID, ProductID: productID})
 	//userLock.Unlock()
 	if userProduct.ID == 0 {
-		response.FailWithDetailed(response.InterfaceDeleted, nil, "该用户接口未购买", context)
+		response.FailWithDetailed(response.InterfaceDeleted, nil, "该用户接口未购买", c)
 		return
 	} else if userProduct.InterfaceStatus != 0 {
-		response.FailWithDetailed(response.InterfaceDeleted, nil, "该用户接口暂不提供服务", context)
+		response.FailWithDetailed(response.InterfaceDeleted, nil, "该用户接口暂不提供服务", c)
 		return
 	}
 	//2.2 取用户(产品余量|钱包账户余额)校验-必须加锁
@@ -40,16 +43,36 @@ func Check(appID string, productID int, context *gin.Context, getData func() ([]
 	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 = costByLeftNum(getData, appID, productID, userProduct, product, param, ip)
+		datas, orderCode, err, errStr = costByLeftNum(getData, appID, productID, userProduct, product, param, ip)
 	case 1:
 		//按账户钱包余额扣费
-		datas, orderCode, err = costByAccountBalance(getData, appID, productID, userProduct, product, param, ip)
+		datas, orderCode, err, errStr = costByAccountBalance(getData, appID, productID, userProduct, product, param, ip)
 	case 2:
 		//优先扣剩余量,剩余量为0,扣钱包余额
 	}
@@ -65,9 +88,13 @@ func Check(appID string, productID int, context *gin.Context, getData func() ([]
 			"user_product_id": userProduct.ID,
 			"create_at":       time.Now().Unix(),
 		})
-		response.OkWithDatas(datas, context)
+		response.FailWithDetailed(response.SUCCESS, datas, "OK", c)
 	} else {
-		global.Logger.Error("数据库操作失败", zap.Any("error:", err))
-		response.FailWithDetailed(response.InterfaceDeleted, nil, "查询失败", context)
+		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)
+		}
 	}
 }

+ 15 - 7
utils/cost_by_account_balance.go

@@ -2,14 +2,13 @@ package utils
 
 import (
 	"errors"
+	"fmt"
 	"log"
 	"sfbase/global"
 	"sfbase/utils"
 	"sfis/db"
+	"sfis/lock"
 	"sfis/model"
-	"time"
-
-	"fmt"
 
 	"go.uber.org/zap"
 	"gorm.io/gorm"
@@ -18,7 +17,7 @@ import (
 /**
 扣账户余额
 */
-func costByAccountBalance(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) {
+func costByAccountBalance(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
 	//productUnit := product.UnitPrice
 	// if productType == 0 {
@@ -30,21 +29,28 @@ func costByAccountBalance(getData func() ([]map[string]interface{}, int, error),
 	// }
 	datas := []map[string]interface{}{}
 	var err error
+	errStr := ""
 	orderCode := ""
 	data, statusCode, _ := execute(getData, appID, productID)
 	beforeJudge, payMoney := beforeCheck(productType, product.UnitPrice, len(data), userProduct)
 	if beforeJudge {
 		global.Logger.Info("交易金额", zap.Any("payMoney:", payMoney))
-		orderCode, err = afterCheck(len(data), payMoney, userProduct, statusCode, param, ip)
 		if err != nil {
+			errStr = "内部错误"
 			global.Logger.Error("数据库操作失败", getUserProductError(appID, productID, err)...)
 		} else {
 			datas = data
+			if len(datas) == 0 {
+				global.Logger.Info("无数据", getUserProductError(appID, productID, err)...)
+			} else {
+				orderCode, err = afterCheck(len(data), payMoney, userProduct, statusCode, param, ip)
+			}
 		}
 	} else {
+		errStr = "余额不足"
 		err = errors.New("剩余余额不足")
 	}
-	return datas, orderCode, err
+	return datas, orderCode, err, errStr
 }
 
 func beforeCheck(productType, unitPrice, dataLen int, userProduct *model.UserProduct) (bool, int) {
@@ -75,7 +81,9 @@ func afterCheck(dataLen, payMoney int, userProduct *model.UserProduct, statusCod
 	userAccount := &model.UserAccount{}
 	db.GetSFISDB().First(userAccount, &model.UserAccount{AppID: userProduct.AppID})
 	var errs error
-	orderCode := fmt.Sprint(time.Now().Year()) + fmt.Sprint(utils.GetRandom(8))
+	lock.OrderCodeLock.Lock()
+	orderCode := utils.GetOrderCode()
+	lock.OrderCodeLock.Unlock()
 	//按次扣费-(每调一次剩余量-1)
 	errs = db.GetSFISDB().Transaction(func(tx *gorm.DB) error {
 		orderBefore := userAccount.Money

+ 18 - 11
utils/cost_by_left_num.go

@@ -2,13 +2,12 @@ package utils
 
 import (
 	"errors"
-	"fmt"
 	"log"
 	"sfbase/global"
 	"sfbase/utils"
 	"sfis/db"
+	"sfis/lock"
 	"sfis/model"
-	"time"
 
 	"gorm.io/gorm"
 )
@@ -16,28 +15,34 @@ import (
 /**
 扣产品剩余量
 */
-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) {
+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, _ := execute(getData, appID, productID)
-		orderCode, err = after(productType, len(data), userProduct, statusCode, param, ip)
-		if err == nil && data != nil && len(data) > 0 {
+		data, statusCode, errs := execute(getData, appID, productID)
+		if errs == nil {
 			datas = data
-		} else {
+			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 {
-				global.Logger.Info("无数据", getUserProductError(appID, productID, err)...)
 			}
+		} else {
+			errStr = "查询错误"
+			global.Logger.Error("查询错误", getUserProductError(appID, productID, err)...)
 		}
 	} else {
+		errStr = "剩余量不足"
 		err = errors.New("剩余量不足")
 	}
-	return datas, orderCode, err
+	return datas, orderCode, err, errStr
 }
 
 /**
@@ -80,7 +85,9 @@ func after(productType int, dataLen int, userProduct *model.UserProduct, statusC
 	productID := userProduct.ProductID
 	userProductID := userProduct.ID
 	var errs error
-	orderCode := fmt.Sprint(time.Now().Year()) + fmt.Sprint(utils.GetRandom(8))
+	lock.OrderCodeLock.Lock()
+	orderCode := utils.GetOrderCode()
+	lock.OrderCodeLock.Unlock()
 	switch productType {
 	case 0:
 		//按次扣费-(每调一次剩余量-1)