github.com/zooyer/miskit@v1.0.71/micro/controller.go (about)

     1  package micro
     2  
     3  import (
     4  	"fmt"
     5  	"net/http"
     6  	"strconv"
     7  	"sync"
     8  
     9  	"github.com/gin-gonic/gin"
    10  	"github.com/zooyer/miskit/errors"
    11  )
    12  
    13  type Response struct {
    14  	Errno   int         `json:"errno"`
    15  	Message string      `json:"message"`
    16  	Data    interface{} `json:"data,omitempty"`
    17  }
    18  
    19  type Controller struct{}
    20  
    21  type Validator interface {
    22  	Valid(ctx *gin.Context) (err error)
    23  }
    24  
    25  var (
    26  	errnoCode  = make(map[int]int)
    27  	errnoMutex sync.Mutex
    28  )
    29  
    30  // RegisterErrorCode 错误码与http状态码映射
    31  func RegisterErrorCode(codes map[int]int) {
    32  	errnoMutex.Lock()
    33  	defer errnoMutex.Unlock()
    34  
    35  	for errno, code := range codes {
    36  		if _, exists := errnoCode[errno]; exists {
    37  			panic(fmt.Sprintf("code: Define called twice for errno %d", errno))
    38  		}
    39  
    40  		errnoCode[errno] = code
    41  	}
    42  }
    43  
    44  // NewResponse 创建响应结构
    45  func NewResponse(data interface{}, err error) (resp Response) {
    46  	if err != nil {
    47  		errno := errors.New(errors.UnknownError, err)
    48  
    49  		resp.Errno = errno.Errno()
    50  
    51  		if err = errno.Unwrap(); err != nil {
    52  			resp.Data = err.Error()
    53  		}
    54  	} else {
    55  		resp.Errno = errors.Success
    56  		resp.Data = data
    57  	}
    58  
    59  	resp.Message = errors.Msg(resp.Errno)
    60  
    61  	return
    62  }
    63  
    64  func (c Controller) ParamInt(ctx *gin.Context, key string) (i int64, err error) {
    65  	if i, err = strconv.ParseInt(ctx.Param(key), 10, 64); err != nil {
    66  		return 0, errors.New(errors.InvalidRequest, err)
    67  	}
    68  
    69  	return
    70  }
    71  
    72  func (c Controller) Bind(ctx *gin.Context, v interface{}) (err error) {
    73  	if err = ctx.Bind(v); err != nil {
    74  		return errors.New(errors.InvalidRequest, err)
    75  	}
    76  
    77  	if validator, ok := v.(Validator); ok {
    78  		if err = validator.Valid(ctx); err != nil {
    79  			return errors.New(errors.InvalidRequest, err)
    80  		}
    81  	}
    82  
    83  	return
    84  }
    85  
    86  func (c Controller) Response(ctx *gin.Context, data interface{}, err error) {
    87  	if err != nil {
    88  		errno := errors.New(errors.UnknownError, err)
    89  		errno.Record(ctx).Metric()
    90  		err = errno
    91  	}
    92  
    93  	resp := NewResponse(data, err)
    94  
    95  	var code = http.StatusOK
    96  	if err != nil {
    97  		code = http.StatusInternalServerError
    98  	}
    99  
   100  	if enoCode, ok := errnoCode[resp.Errno]; ok {
   101  		code = enoCode
   102  	}
   103  
   104  	ctx.AbortWithStatusJSON(code, resp)
   105  }