package utils import ( "bytes" "encoding/json" "fmt" "git.rosy.net.cn/baseapi" "git.rosy.net.cn/jx-print/globals" "git.rosy.net.cn/jx-print/model" "github.com/dchest/captcha" "github.com/gin-gonic/gin" "math/rand" "net/http" "strings" "time" ) var commonInitialisms = []string{"ACL", "API", "ASCII", "CPU", "CSS", "DNS", "EOF", "GUID", "HTML", "HTTP", "HTTPS", "ID", "IP", "JSON", "LHS", "QPS", "RAM", "RHS", "RPC", "SLA", "SMTP", "SQL", "SSH", "TCP", "TLS", "TTL", "UDP", "UI", "UID", "UUID", "URI", "URL", "UTF8", "VM", "XML", "XMPP", "XSRF", "XSS"} var commonInitialismsReplacer *strings.Replacer var uncommonInitialismsReplacer *strings.Replacer func init() { var commonInitialismsForReplacer []string var uncommonInitialismsForReplacer []string for _, initialism := range commonInitialisms { commonInitialismsForReplacer = append(commonInitialismsForReplacer, initialism, strings.Title(strings.ToLower(initialism))) uncommonInitialismsForReplacer = append(uncommonInitialismsForReplacer, strings.Title(strings.ToLower(initialism)), initialism) } commonInitialismsReplacer = strings.NewReplacer(commonInitialismsForReplacer...) uncommonInitialismsReplacer = strings.NewReplacer(uncommonInitialismsForReplacer...) } var ( letterBytes = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" letterBytesNum = "0123456789" ) func RandStringBytes(n int) string { b := make([]byte, n) for i := range b { b[i] = letterBytes[rand.Intn(len(letterBytes))] } return string(b) } func RandStringBytesWithNumber(n int) string { b := make([]byte, n) for i := range b { b[i] = letterBytesNum[rand.Intn(len(letterBytesNum))] } return string(b) } func Captcha(c *gin.Context, length ...int) { l := captcha.DefaultLen w, h := 107, 36 if len(length) == 1 { l = length[0] } if len(length) == 2 { w = length[1] } if len(length) == 3 { h = length[2] } captchaId := captcha.NewLen(l) //session := sessions.Default(c) //session.Set(c.ClientIP()+model.SessionKey, captchaId) //_ = session.Save() if err := SetKey(c.ClientIP()+model.SessionKey, captchaId, time.Minute*5); err == nil { _ = Serve(c.Writer, c.Request, captchaId, ".png", "zh", false, w, h) } } func Serve(w http.ResponseWriter, r *http.Request, id, ext, lang string, download bool, width, height int) error { w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate") w.Header().Set("Pragma", "no-cache") w.Header().Set("Expires", "0") var content bytes.Buffer switch ext { case ".png": w.Header().Set("Content-Type", "image/png") _ = captcha.WriteImage(&content, id, width, height) case ".wav": w.Header().Set("Content-Type", "audio/x-wav") _ = captcha.WriteAudio(&content, id, lang) default: return captcha.ErrNotFound } if download { w.Header().Set("Content-Type", "application/octet-stream") } http.ServeContent(w, r, id+ext, time.Time{}, bytes.NewReader(content.Bytes())) return nil } //驼峰转下划线 func UnMarshalHr(name string) string { const ( lower = false upper = true ) if name == "" { return "" } var ( value = commonInitialismsReplacer.Replace(name) buf = bytes.NewBufferString("") lastCase, currCase, nextCase, nextNumber bool ) for i, v := range value[:len(value)-1] { nextCase = bool(value[i+1] >= 'A' && value[i+1] <= 'Z') nextNumber = bool(value[i+1] >= '0' && value[i+1] <= '9') if i > 0 { if currCase == upper { if lastCase == upper && (nextCase == upper || nextNumber == upper) { buf.WriteRune(v) } else { if value[i-1] != '_' && value[i+1] != '_' { buf.WriteRune('_') } buf.WriteRune(v) } } else { buf.WriteRune(v) if i == len(value)-2 && (nextCase == upper && nextNumber == lower) { buf.WriteRune('_') } } } else { currCase = upper buf.WriteRune(v) } lastCase = currCase currCase = nextCase } buf.WriteByte(value[len(value)-1]) s := strings.ToLower(buf.String()) return s } func UnmarshalUseNumber(data []byte, result interface{}) error { err := TryUnmarshalUseNumber(data, result) if err != nil { globals.SugarLogger.Infof("decode data:%v, error:%v", string(data), err) } return err } func TryUnmarshalUseNumber(data []byte, result interface{}) error { d := json.NewDecoder(bytes.NewReader(data)) d.UseNumber() return d.Decode(result) } func BuildErr(errs []error) (err error) { var errStr = strings.Builder{} for _, v := range errs { errStr.WriteString(v.Error()) } return fmt.Errorf(errStr.String()) } func Format4Output(obj interface{}, isSingleLine bool) (retVal string) { retVal, ok := obj.(string) if !ok { var ( result []byte err error ) if isSingleLine { if result, err = json.Marshal(obj); err == nil { retVal = string(result) } } else { if result, err = json.MarshalIndent(obj, "", "\t"); err == nil { retVal = string(result) } } if err != nil { baseapi.SugarLogger.Infof("Format4Output Marshal:%v failed with error:%v", obj, err) retVal = fmt.Sprintf("%v", obj) } } return retVal }