mirror of
https://github.com/unti-io/go-utils.git
synced 2025-11-01 03:52:44 +08:00
v1.0.5
v1.0.5
This commit is contained in:
3
go.mod
3
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
|
||||
|
||||
11
go.sum
11
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=
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
185
utils/file.go
185
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
|
||||
}
|
||||
}
|
||||
@@ -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中的值 - 支持多级
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
// 如果有参数,则格式化
|
||||
|
||||
Reference in New Issue
Block a user