| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 | package apiimport (	"errors"	"github.com/0xJacky/Nginx-UI/model"	"github.com/gin-gonic/gin"	"github.com/go-playground/validator/v10"	"github.com/uozi-tech/cosy/logger"	"net/http"	"reflect"	"regexp"	"strings")func CurrentUser(c *gin.Context) *model.User {	return c.MustGet("user").(*model.User)}func ErrHandler(c *gin.Context, err error) {	logger.GetLogger().Errorln(err)	c.JSON(http.StatusInternalServerError, gin.H{		"message": err.Error(),	})}type ValidError struct {	Key     string	Message string}func BindAndValid(c *gin.Context, target interface{}) bool {	err := c.ShouldBindJSON(target)	if err != nil {		logger.Error("bind err", err)		var verrs validator.ValidationErrors		ok := errors.As(err, &verrs)		if !ok {			c.JSON(http.StatusNotAcceptable, gin.H{				"message": "Requested with wrong parameters",				"code":    http.StatusNotAcceptable,			})			return false		}		t := reflect.TypeOf(target).Elem()		errorsMap := make(map[string]interface{})		for _, value := range verrs {			var path []string			namespace := strings.Split(value.StructNamespace(), ".")			// logger.Debug(t.Name(), namespace)			if t.Name() != "" && len(namespace) > 1 {				namespace = namespace[1:]			}			getJsonPath(t, namespace, &path)			insertError(errorsMap, path, value.Tag())		}		c.JSON(http.StatusNotAcceptable, gin.H{			"errors":  errorsMap,			"message": "Requested with wrong parameters",			"code":    http.StatusNotAcceptable,		})		return false	}	return true}// findField recursively finds the field in a nested structfunc getJsonPath(t reflect.Type, fields []string, path *[]string) {	field := fields[0]	// used in case of array	var index string	if field[len(field)-1] == ']' {		re := regexp.MustCompile(`(\w+)\[(\d+)\]`)		matches := re.FindStringSubmatch(field)		if len(matches) > 2 {			field = matches[1]			index = matches[2]		}	}	f, ok := t.FieldByName(field)	if !ok {		return	}	*path = append(*path, f.Tag.Get("json"))	if index != "" {		*path = append(*path, index)	}	if len(fields) > 1 {		subFields := fields[1:]		getJsonPath(f.Type, subFields, path)	}}// insertError inserts an error into the errors mapfunc insertError(errorsMap map[string]interface{}, path []string, errorTag string) {	if len(path) == 0 {		return	}	jsonTag := path[0]	if len(path) == 1 {		// Last element in the path, set the error		errorsMap[jsonTag] = errorTag		return	}	// Create a new map if necessary	if _, ok := errorsMap[jsonTag]; !ok {		errorsMap[jsonTag] = make(map[string]interface{})	}	// Recursively insert into the nested map	subMap, _ := errorsMap[jsonTag].(map[string]interface{})	insertError(subMap, path[1:], errorTag)}
 |