diff --git a/go.mod b/go.mod index 73ffee4..3bb4903 100644 --- a/go.mod +++ b/go.mod @@ -3,8 +3,6 @@ module github.com/unti-io/go-utils go 1.20 require ( - github.com/fsnotify/fsnotify v1.6.0 - github.com/goccy/go-json v0.10.2 github.com/json-iterator/go v1.1.12 github.com/spf13/cast v1.5.0 github.com/spf13/viper v1.15.0 @@ -12,6 +10,7 @@ require ( ) require ( + github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect diff --git a/go.sum b/go.sum index 80a90aa..291d015 100644 --- a/go.sum +++ b/go.sum @@ -61,8 +61,6 @@ github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbS github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= -github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -145,8 +143,6 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU= -github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek= github.com/pelletier/go-toml/v2 v2.0.7 h1:muncTPStnKRos5dpVKULv2FVd4bMOhNePj9CjgDb8Us= github.com/pelletier/go-toml/v2 v2.0.7/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -156,8 +152,6 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= -github.com/spf13/afero v1.9.3 h1:41FoI0fD7OR7mGcKE/aOiLkGreyf8ifIOQmJANWogMk= -github.com/spf13/afero v1.9.3/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y= github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM= github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= @@ -198,7 +192,6 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= @@ -322,8 +315,6 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -335,8 +326,6 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= -golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/utils/app.go b/utils/app.go index bbeec98..188c352 100644 --- a/utils/app.go +++ b/utils/app.go @@ -41,7 +41,6 @@ func init() { Is.Map = IsMap Is.SliceSlice = IsSliceSlice Is.MapAny = IsMapAny - // Env.Toml = En vToml Get.Type = GetType Get.Ip = GetIp In.Array = InArray @@ -67,8 +66,6 @@ func init() { Parse.ParamsBefore = ParseParamsBefore Parse.Params = ParseParams Net.Tcping = NetTcping - File.List = FileList - File.Bytes = FileBytes Mime.Type = MimeType } @@ -152,7 +149,7 @@ var Struct struct { var Json struct { Encode func(value any) (result string) - Decode func(value string) (result any) + Decode func(value any) (result any) Get func(value any, key any) (result any, err error) } @@ -167,10 +164,6 @@ var Parse struct { var Net struct { Tcping func(host any, opts ...map[string]any) (ok bool, detail []map[string]any) } -var File struct { - List func(path any, opt ...map[string]any) (slice []string) - Bytes func(path any) []byte -} var Mime struct { Type func(suffix any) (mime string) } diff --git a/utils/curl.go b/utils/curl.go index aec3691..7f41343 100644 --- a/utils/curl.go +++ b/utils/curl.go @@ -138,13 +138,13 @@ func (this *CurlStruct) Headers(headers map[string]any) *CurlStruct { return this } -// Param - 定义请求参数 +// Query - 定义请求参数 func (this *CurlStruct) Query(key any, value any) *CurlStruct { this.request.Query[cast.ToString(key)] = cast.ToString(value) return this } -// Params - 批量定义请求参数 +// Querys - 批量定义请求参数 func (this *CurlStruct) Querys(params map[string]any) *CurlStruct { for key, val := range params { this.request.Query[cast.ToString(key)] = cast.ToString(val) @@ -212,7 +212,11 @@ func (this *CurlStruct) Send() *CurlResponse { body := &bytes.Buffer{} writer := multipart.NewWriter(body) for key, val := range this.request.Data { - writer.WriteField(key, val) + err := writer.WriteField(key, val) + if err != nil { + this.response.Error = err + return this.response + } } // add file field to request if file, ok := this.request.Body.(*multipart.FileHeader); ok { @@ -226,7 +230,13 @@ func (this *CurlStruct) Send() *CurlResponse { this.response.Error = err return this.response } - defer item.Close() + defer func(item multipart.File) { + err := item.Close() + if err != nil { + this.response.Error = err + return + } + }(item) _, err = io.Copy(filePart, item) if err != nil { this.response.Error = err @@ -261,7 +271,13 @@ func (this *CurlStruct) Send() *CurlResponse { this.response.Error = err return this.response } - defer response.Body.Close() + defer func(Body io.ReadCloser) { + err := Body.Close() + if err != nil { + this.response.Error = err + return + } + }(response.Body) // Read response body body, err := io.ReadAll(response.Body) diff --git a/utils/file.go b/utils/file.go index 2e8f101..bb86098 100644 --- a/utils/file.go +++ b/utils/file.go @@ -1,11 +1,160 @@ package utils import ( + "errors" "github.com/spf13/cast" + "io" "os" "path/filepath" ) +type FileRequest struct { + // 文件名 + Name string + // 文件目录 + Path string + // 文件后缀 + Ext string +} + +// FileStruct - File 结构体 +type FileStruct struct { + request *FileRequest + response *FileResponse +} + +type FileResponse struct { + Error error + Result string + Byte []byte +} + +func File(model ...FileStruct) *FileStruct { + + if len(model) == 0 { + model = append(model, FileStruct{}) + } + + return &model[0] +} + +// Path 设置文件路径(包含文件名,如:/tmp/test.txt) +func (this *FileStruct) Path(path any) *FileStruct { + this.request.Path = cast.ToString(path) + return this +} + +// Name 设置文件名(不包含路径,如:test.txt) +func (this *FileStruct) Name(name any) *FileStruct { + this.request.Name = cast.ToString(name) + return this +} + +// Ext 设置文件后缀(如:.txt) +func (this *FileStruct) Ext(ext any) *FileStruct { + this.request.Ext = cast.ToString(ext) + return this +} + +// Save 保存文件 +func (this *FileStruct) Save(reader io.Reader, path ...string) (result *FileResponse) { + + if len(path) != 0 { + this.request.Path = path[0] + } + + if IsEmpty(this.request.Path) { + this.response.Error = errors.New("文件路径不能为空") + return this.response + } + + filePath := cast.ToString(path) + + dir := filepath.Dir(filePath) + if _, err := os.Stat(dir); os.IsNotExist(err) { + // 目录不存在,需要创建 + if err := os.MkdirAll(dir, 0755); err != nil { + this.response.Error = err + return this.response + } + } + + // 创建文件 + file, err := os.Create(filePath) + if err != nil { + this.response.Error = err + return this.response + } + + // 关闭文件 + defer func(file *os.File) { + err := file.Close() + if err != nil { + this.response.Error = err + return + } + }(file) + + // 将文件通过流的方式写入磁盘 + _, err = io.Copy(file, reader) + if err != nil { + this.response.Error = err + return this.response + } + + return nil +} + +// Byte 获取文件字节 +func (this *FileStruct) Byte(path ...any) (result *FileResponse) { + + if len(path) != 0 { + this.request.Path = cast.ToString(path[0]) + } + + if IsEmpty(this.request.Path) { + this.response.Error = errors.New("文件路径不能为空") + return this.response + } + + // 读取文件 + file, err := os.Open(cast.ToString(path)) + if err != nil { + return + } + defer func(file *os.File) { + err := file.Close() + if err != nil { + + } + }(file) + + // // 获取文件大小 + // info, _ := file.Stat() + // size := info.Size() + // // 读取文件 + // data := make([]byte, size) + // file.Read(data) + // return data + + bytes := make([]byte, 1024) + + // 分批次读取 + buf := make([]byte, 1024) + for { + line, err := file.Read(buf) + if err != nil { + break + } + bytes = append(bytes, buf[:line]...) + } + + this.response.Byte = bytes + this.response.Result = string(bytes) + + return this.response +} + // FileList 获取指定目录下的所有文件 func FileList(path any, opt ...map[string]any) (slice []string) { @@ -75,38 +224,4 @@ func FileList(path any, opt ...map[string]any) (slice []string) { } return -} - -// FileBytes 获取文件字节 -func FileBytes(path any) (result []byte) { - // 读取文件 - file, err := os.Open(cast.ToString(path)) - if err != nil { - return - } - defer func(file *os.File) { - err := file.Close() - if err != nil { - - } - }(file) - - // // 获取文件大小 - // info, _ := file.Stat() - // size := info.Size() - // // 读取文件 - // data := make([]byte, size) - // file.Read(data) - // return data - - // 分批次读取 - buf := make([]byte, 1024) - for { - line, err := file.Read(buf) - if err != nil { - break - } - result = append(result, buf[:line]...) - } - return -} +} \ No newline at end of file diff --git a/utils/json.go b/utils/json.go index f7e4f94..6bf7cbe 100644 --- a/utils/json.go +++ b/utils/json.go @@ -10,19 +10,13 @@ import ( // JsonEncode 编码 func JsonEncode(data any) (result string) { text, err := json.Marshal(data) - if err != nil { - return "" - } - return string(text) + return Ternary(err != nil, "", string(text)) } // JsonDecode 解码 -func JsonDecode(data string) (result any) { - err := json.Unmarshal([]byte(data), &result) - if err != nil { - return nil - } - return result +func JsonDecode(data any) (result any) { + err := json.Unmarshal([]byte(cast.ToString(data)), &result) + return Ternary(err != nil, nil, result) } // JsonGet 获取json中的值 - 支持多级 diff --git a/utils/lang.go b/utils/lang.go index aa5c2a1..906dc3a 100644 --- a/utils/lang.go +++ b/utils/lang.go @@ -32,19 +32,18 @@ func Lang(model ...LangModel) *LangModel { func (this *LangModel) Value(key any, args ...any) (result any) { // 读取语言包 - bytes := FileBytes(this.Directory + this.Lang + "." + this.Mode) - text := string(bytes) - keyStr := cast.ToString(key) + bytes := File().Byte(this.Directory + this.Lang + "." + this.Mode) + text := cast.ToString(key) // 解析语言包 - lang := cast.ToStringMap(JsonDecode(text)) + lang := cast.ToStringMap(JsonDecode(bytes.Result)) // 获取语言 - result = lang[keyStr] + result = lang[text] // 如果没有找到语言,通过javascript风格获取 if IsEmpty(result) { - item, err := JsonGet(text, keyStr) + item, err := JsonGet(bytes.Result, text) if err == nil { result = item } @@ -52,7 +51,7 @@ func (this *LangModel) Value(key any, args ...any) (result any) { // 如果没有找到语言,则返回原文 if IsEmpty(result) { - return keyStr + return text } // 如果有参数,则格式化