Compare commits
33 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 99cbdec579 | |||
| 69cbec24d4 | |||
| d5a6b53bb0 | |||
| aad37f1b6f | |||
| 30e961cecc | |||
| 033fc33150 | |||
| 3055b15855 | |||
| 98f0082d44 | |||
| 89c8d06bcf | |||
| 7fa8b6eb7d | |||
| 2181cab5a5 | |||
| ac98d52472 | |||
| f297ca9d12 | |||
| 076aa26036 | |||
| 00018cb47e | |||
| 6699d8ac32 | |||
| 76f4f0b4d2 | |||
| 5d33124e52 | |||
| 2786c69949 | |||
| 81846cb1e9 | |||
| 9e5c546f1d | |||
| 662a2f13c5 | |||
| 47c569f6fb | |||
| 1ae15aeb08 | |||
| 311bf643d0 | |||
| c856c6e2c3 | |||
| 269771f982 | |||
| 4d8cabacc5 | |||
| 06b3f40905 | |||
| 508f139da2 | |||
| 7b8caaca53 | |||
| 12a743d8da | |||
| 19d62ab927 |
24
Dockerfile
Normal file
24
Dockerfile
Normal file
@@ -0,0 +1,24 @@
|
||||
# 阶段1: 构建
|
||||
FROM golang:alpine AS builder
|
||||
|
||||
RUN apk add --no-cache git ca-certificates tzdata
|
||||
|
||||
ENV TZ=Asia/Shanghai
|
||||
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
|
||||
|
||||
ENV GO111MODULE=on
|
||||
ENV GOPROXY=https://goproxy.cn,direct
|
||||
ENV CGO_ENABLED=0
|
||||
ENV GOTOOLCHAIN=auto
|
||||
WORKDIR /build
|
||||
|
||||
COPY . .
|
||||
|
||||
RUN go mod download && go mod tidy
|
||||
|
||||
RUN go build -ldflags="-s -w" -o main ./main.go
|
||||
|
||||
|
||||
EXPOSE 3008
|
||||
|
||||
CMD ["./main"]
|
||||
71
config.yml
71
config.yml
@@ -5,7 +5,9 @@ server:
|
||||
rate:
|
||||
limit: 200
|
||||
burst: 300
|
||||
|
||||
cache:
|
||||
localTTL: 60
|
||||
redisTTL: 300
|
||||
# Database.
|
||||
database:
|
||||
default:
|
||||
@@ -13,15 +15,18 @@ database:
|
||||
host: "116.204.74.41"
|
||||
port: "15432"
|
||||
user: "postgres"
|
||||
pass: "123456"
|
||||
pass: "Bjang09@686^*^"
|
||||
name: "oss"
|
||||
role: "master"
|
||||
maxIdle: "5"
|
||||
maxOpen: "20"
|
||||
maxLifetime: "60s"
|
||||
charset: "utf8mb4" #数据库编码
|
||||
debug: true
|
||||
dryRun: false #空跑
|
||||
prefix: "oss_" # (可选)表名前缀
|
||||
role: "master" # (可选)数据库主从角色(master/slave),默认为master。如果不使用应用主从机制请不配置或留空即可。
|
||||
debug: false # (可选)开启调试模式
|
||||
dryRun: false # (可选)ORM空跑(只读不写)
|
||||
charset: "utf8" # (可选)数据库编码(如: utf8mb4/utf8/gbk/gb2312),一般设置为utf8mb4。默认为utf8。
|
||||
timezone: "Asia/Shanghai" # (可选)时区配置,例如:Local
|
||||
maxIdle: 5 # (可选)连接池最大闲置的连接数(默认10)
|
||||
maxOpen: 20 # (可选)连接池最大打开的连接数(默认无限制)
|
||||
maxLifetime: "30s" # (可选)连接对象可重复使用的时间长度(默认30秒)
|
||||
maxIdleConnTime: "30s" # (可选,v2.10新增)连接池中空闲连接的最大生存时间(默认30秒)。可以通过配置文件或SetConnMaxIdleTime方法设置,避免长时间空闲连接占用资源。
|
||||
createdAt: "created_at" # (可选)自动创建时间字段名称
|
||||
updatedAt: "updated_at" # (可选)自动更新时间字段名称
|
||||
deletedAt: "deleted_at" # (可选)软删除时间字段名称
|
||||
@@ -30,19 +35,43 @@ database:
|
||||
host: "116.204.74.41"
|
||||
port: "15432"
|
||||
user: "postgres"
|
||||
pass: "123456"
|
||||
pass: "Bjang09@686^*^"
|
||||
name: "oss"
|
||||
role: "slave"
|
||||
maxIdle: "5"
|
||||
maxOpen: "20"
|
||||
maxLifetime: "60s"
|
||||
charset: "utf8mb4" #数据库编码
|
||||
debug: true
|
||||
dryRun: false #空跑
|
||||
prefix: "oss_" # (可选)表名前缀
|
||||
role: "slave" # (可选)数据库主从角色(master/slave),默认为master。如果不使用应用主从机制请不配置或留空即可。
|
||||
debug: false # (可选)开启调试模式
|
||||
dryRun: false # (可选)ORM空跑(只读不写)
|
||||
charset: "utf8" # (可选)数据库编码(如: utf8mb4/utf8/gbk/gb2312),一般设置为utf8mb4。默认为utf8。
|
||||
timezone: "Asia/Shanghai" # (可选)时区配置,例如:Local
|
||||
maxIdle: 5 # (可选)连接池最大闲置的连接数(默认10)
|
||||
maxOpen: 20 # (可选)连接池最大打开的连接数(默认无限制)
|
||||
maxLifetime: "30s" # (可选)连接对象可重复使用的时间长度(默认30秒)
|
||||
maxIdleConnTime: "30s" # (可选,v2.10新增)连接池中空闲连接的最大生存时间(默认30秒)。可以通过配置文件或SetConnMaxIdleTime方法设置,避免长时间空闲连接占用资源。
|
||||
createdAt: "created_at" # (可选)自动创建时间字段名称
|
||||
updatedAt: "updated_at" # (可选)自动更新时间字段名称
|
||||
deletedAt: "deleted_at" # (可选)软删除时间字段名称
|
||||
timeMaintainDisabled: false # (可选)是否完全关闭时间更新特性,为true时CreatedAt/UpdatedAt/DeletedAt都将失效
|
||||
# tenant-1:
|
||||
# - type: "pgsql"
|
||||
# host: "localhost"
|
||||
# port: "5432"
|
||||
# user: "postgres"
|
||||
# pass: "123456"
|
||||
# name: "tenant-1"
|
||||
# role: "master"
|
||||
# prefix: "oss_" # (可选)表名前缀
|
||||
# debug: false # (可选)开启调试模式
|
||||
# dryRun: false # (可选)ORM空跑(只读不写)
|
||||
# charset: "utf8" # (可选)数据库编码(如: utf8mb4/utf8/gbk/gb2312),一般设置为utf8mb4。默认为utf8。
|
||||
# timezone: "Asia/Shanghai" # (可选)时区配置,例如:Local
|
||||
# maxIdle: 5 # (可选)连接池最大闲置的连接数(默认10)
|
||||
# maxOpen: 20 # (可选)连接池最大打开的连接数(默认无限制)
|
||||
# maxLifetime: "30s" # (可选)连接对象可重复使用的时间长度(默认30秒)
|
||||
# maxIdleConnTime: "30s" # (可选,v2.10新增)连接池中空闲连接的最大生存时间(默认30秒)。可以通过配置文件或SetConnMaxIdleTime方法设置,避免长时间空闲连接占用资源。
|
||||
# createdAt: "created_at" # (可选)自动创建时间字段名称
|
||||
# updatedAt: "updated_at" # (可选)自动更新时间字段名称
|
||||
# deletedAt: "deleted_at" # (可选)软删除时间字段名称
|
||||
# timeMaintainDisabled: false # (可选)是否完全关闭时间更新特性,为true时CreatedAt/UpdatedAt/DeletedAt都将失效
|
||||
|
||||
redis:
|
||||
# 集群模式配置方法
|
||||
@@ -66,17 +95,13 @@ jaeger: #链路追踪
|
||||
minio:
|
||||
endpoint: "116.204.74.41:9000" # 核心:仅协议+主机+端口,无路径/末尾斜杠
|
||||
accessKey: "admin" # 访问密钥(本地默认)
|
||||
secretKey: "12345678" # 秘密密钥(本地默认)
|
||||
secretKey: "Bjang09@686^*^" # 秘密密钥(本地默认)
|
||||
secure: false # 本地 MinIO 关闭 SSL(生产按需改为 true)
|
||||
region: "us-east-1" # 与 MinIO 服务端 REGION 一致(默认 us-east-1)
|
||||
|
||||
# 文件上传服务地址,与oss模块minio中的endpoint一致
|
||||
filePrefix: "116.204.74.41:9000"
|
||||
filePrefix: "http://116.204.74.41:9000"
|
||||
|
||||
# 文件存储初始化容量大小配置
|
||||
oss:
|
||||
capacitySize: 500 #文件存储初始化容量(单位MB)
|
||||
|
||||
cache:
|
||||
localTTL: 60
|
||||
redisTTL: 300
|
||||
@@ -1,7 +0,0 @@
|
||||
package consts
|
||||
|
||||
// MongoDB集合名称常量
|
||||
const (
|
||||
FileCollection = "file"
|
||||
TenantOssTotalCollection = "tenant_oss_total"
|
||||
)
|
||||
7
consts/table_name.go
Normal file
7
consts/table_name.go
Normal file
@@ -0,0 +1,7 @@
|
||||
package consts
|
||||
|
||||
// 数据库表名
|
||||
const (
|
||||
TableNameFile = "file"
|
||||
TableNameTenantOssTotal = "tenant_oss_total"
|
||||
)
|
||||
@@ -4,6 +4,8 @@ import (
|
||||
"context"
|
||||
"oss/model/dto"
|
||||
"oss/service"
|
||||
|
||||
"gitea.redpowerfuture.com/red-future/common/beans"
|
||||
)
|
||||
|
||||
type file struct{}
|
||||
@@ -14,7 +16,24 @@ var File = new(file)
|
||||
func init() {
|
||||
}
|
||||
|
||||
// DownloadToFile 下载文件到本地
|
||||
func (c *file) DownloadToFile(ctx context.Context, req *dto.DownloadToFileReq) (res *beans.ResponseEmpty, err error) {
|
||||
err = service.File.DownloadToFile(ctx, req)
|
||||
return
|
||||
}
|
||||
|
||||
// DownloadToBrowser 下载文件到浏览器
|
||||
func (c *file) DownloadToBrowser(ctx context.Context, req *dto.DownloadToBrowserReq) (res *beans.ResponseEmpty, err error) {
|
||||
err = service.File.DownloadToBrowser(ctx, req)
|
||||
return
|
||||
}
|
||||
|
||||
// UploadFile 上传文件
|
||||
func (c *file) UploadFile(ctx context.Context, req *dto.UploadFileReq) (res *dto.UploadFileRes, err error) {
|
||||
return service.File.UploadFile(ctx, req)
|
||||
}
|
||||
|
||||
// UploadFileBytes 上传文件(字节流)
|
||||
func (c *file) UploadFileBytes(ctx context.Context, req *dto.UploadFileBytesReq) (res *dto.UploadFileRes, err error) {
|
||||
return service.File.UploadFileBytes(ctx, req)
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"oss/model/dto"
|
||||
"oss/model/entity"
|
||||
|
||||
"gitea.com/red-future/common/db/gfdb"
|
||||
"gitea.redpowerfuture.com/red-future/common/db/gfdb"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
)
|
||||
|
||||
@@ -20,7 +20,7 @@ func (d *file) Insert(ctx context.Context, req *dto.UploadFile) (id int64, err e
|
||||
if err = gconv.Struct(req, &res); err != nil {
|
||||
return
|
||||
}
|
||||
r, err := gfdb.DB(ctx).Model(ctx, consts.FileCollection).Insert(&res)
|
||||
r, err := gfdb.DB(ctx).Model(ctx, consts.TableNameFile).Insert(&res)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"oss/model/dto"
|
||||
"oss/model/entity"
|
||||
|
||||
"gitea.com/red-future/common/db/gfdb"
|
||||
"gitea.redpowerfuture.com/red-future/common/db/gfdb"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
)
|
||||
|
||||
@@ -20,7 +20,7 @@ func (d *tenantOssTotal) SaveOrUpdate(ctx context.Context, updateData []*dto.Upd
|
||||
if err = gconv.Structs(updateData, &res); err != nil {
|
||||
return
|
||||
}
|
||||
r, err := gfdb.DB(ctx).Model(ctx, consts.TenantOssTotalCollection).Data(res).OnConflict(entity.TenantOssCol.TenantId).Save()
|
||||
r, err := gfdb.DB(ctx).Model(ctx, consts.TableNameTenantOssTotal).Data(res).OnConflict(entity.TenantOssCol.TenantId).Save()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@@ -28,7 +28,7 @@ func (d *tenantOssTotal) SaveOrUpdate(ctx context.Context, updateData []*dto.Upd
|
||||
}
|
||||
|
||||
func (d *tenantOssTotal) GetOneByTenantId(ctx context.Context, req *dto.GetByTenantIdReq) (res *entity.TenantOssTotal, err error) {
|
||||
model := gfdb.DB(ctx).Model(ctx, consts.TenantOssTotalCollection).Where(entity.TenantOssCol.TenantId, req.TenantId)
|
||||
model := gfdb.DB(ctx).Model(ctx, consts.TableNameTenantOssTotal).Where(entity.TenantOssCol.TenantId, req.TenantId)
|
||||
record, err := model.One()
|
||||
if err != nil {
|
||||
return
|
||||
|
||||
60
go.mod
60
go.mod
@@ -1,31 +1,32 @@
|
||||
module oss
|
||||
|
||||
go 1.26.0
|
||||
go 1.26.1
|
||||
|
||||
require (
|
||||
gitea.com/red-future/common v0.0.4
|
||||
github.com/gogf/gf/contrib/drivers/pgsql/v2 v2.10.0
|
||||
github.com/gogf/gf/contrib/nosql/redis/v2 v2.9.5
|
||||
github.com/gogf/gf/v2 v2.10.0
|
||||
gitea.redpowerfuture.com/red-future/common v0.0.23
|
||||
github.com/gogf/gf/contrib/drivers/pgsql/v2 v2.10.2
|
||||
github.com/gogf/gf/contrib/nosql/redis/v2 v2.10.2
|
||||
github.com/gogf/gf/v2 v2.10.2
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/minio/minio-go/v7 v7.2.0
|
||||
)
|
||||
|
||||
//replace gitea.com/red-future/common => ../common
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v1.5.0 // indirect
|
||||
github.com/BurntSushi/toml v1.6.0 // indirect
|
||||
github.com/armon/go-metrics v0.4.1 // indirect
|
||||
github.com/bwmarrin/snowflake v0.3.0 // indirect
|
||||
github.com/cenkalti/backoff/v5 v5.0.3 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/clbanning/mxj/v2 v2.7.0 // indirect
|
||||
github.com/clipperhouse/uax29/v2 v2.7.0 // indirect
|
||||
github.com/dgraph-io/badger/v4 v4.2.0 // indirect
|
||||
github.com/dgraph-io/ristretto v0.1.1 // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/emirpasic/gods/v2 v2.0.0-alpha // indirect
|
||||
github.com/fatih/color v1.18.0 // indirect
|
||||
github.com/fatih/color v1.19.0 // indirect
|
||||
github.com/fsnotify/fsnotify v1.9.0 // indirect
|
||||
github.com/go-ini/ini v1.67.0 // indirect
|
||||
github.com/go-ego/gse v1.0.2 // indirect
|
||||
github.com/go-logr/logr v1.4.3 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/gogf/gf/contrib/registry/consul/v2 v2.9.5 // indirect
|
||||
@@ -37,8 +38,7 @@ require (
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/golang/snappy v1.0.0 // indirect
|
||||
github.com/google/flatbuffers v1.12.1 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/gorilla/websocket v1.5.3 // indirect
|
||||
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect
|
||||
github.com/grokify/html-strip-tags-go v0.1.0 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 // indirect
|
||||
github.com/hashicorp/consul/api v1.26.1 // indirect
|
||||
@@ -50,17 +50,16 @@ require (
|
||||
github.com/hashicorp/go-rootcerts v1.0.2 // indirect
|
||||
github.com/hashicorp/golang-lru v1.0.2 // indirect
|
||||
github.com/hashicorp/serf v0.10.1 // indirect
|
||||
github.com/klauspost/compress v1.18.0 // indirect
|
||||
github.com/klauspost/compress v1.18.6 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.11 // indirect
|
||||
github.com/klauspost/crc32 v1.3.0 // indirect
|
||||
github.com/lib/pq v1.10.9 // indirect
|
||||
github.com/magiconair/properties v1.8.10 // indirect
|
||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.16 // indirect
|
||||
github.com/minio/crc64nvme v1.1.0 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.23 // indirect
|
||||
github.com/minio/crc64nvme v1.1.1 // indirect
|
||||
github.com/minio/md5-simd v1.1.2 // indirect
|
||||
github.com/minio/minio-go/v7 v7.0.97 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/olekukonko/errors v1.1.0 // indirect
|
||||
@@ -68,17 +67,16 @@ require (
|
||||
github.com/olekukonko/tablewriter v1.1.0 // indirect
|
||||
github.com/philhofer/fwd v1.2.0 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/r3labs/diff/v2 v2.15.1 // indirect
|
||||
github.com/redis/go-redis/v9 v9.12.1 // indirect
|
||||
github.com/rivo/uniseg v0.4.7 // indirect
|
||||
github.com/rs/xid v1.6.0 // indirect
|
||||
github.com/stretchr/objx v0.5.2 // indirect
|
||||
github.com/tiger1103/gfast-token v1.0.10 // indirect
|
||||
github.com/tinylib/msgp v1.3.0 // indirect
|
||||
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
|
||||
github.com/xdg-go/scram v1.1.2 // indirect
|
||||
github.com/xdg-go/stringprep v1.0.4 // indirect
|
||||
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect
|
||||
go.mongodb.org/mongo-driver/v2 v2.4.1 // indirect
|
||||
github.com/tinylib/msgp v1.6.1 // indirect
|
||||
github.com/vcaesar/cedar v0.30.0 // indirect
|
||||
github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect
|
||||
github.com/zeebo/xxh3 v1.1.0 // indirect
|
||||
go.mongodb.org/mongo-driver/v2 v2.4.0 // indirect
|
||||
go.opencensus.io v0.23.0 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
||||
go.opentelemetry.io/otel v1.38.0 // indirect
|
||||
@@ -88,15 +86,17 @@ require (
|
||||
go.opentelemetry.io/otel/sdk v1.38.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.38.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.7.1 // indirect
|
||||
golang.org/x/crypto v0.45.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20250128144449-3edf0e91c1ae // indirect
|
||||
golang.org/x/net v0.47.0 // indirect
|
||||
golang.org/x/sync v0.18.0 // indirect
|
||||
golang.org/x/sys v0.38.0 // indirect
|
||||
golang.org/x/text v0.31.0 // indirect
|
||||
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||
golang.org/x/crypto v0.51.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 // indirect
|
||||
golang.org/x/net v0.53.0 // indirect
|
||||
golang.org/x/sys v0.44.0 // indirect
|
||||
golang.org/x/text v0.37.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 // indirect
|
||||
google.golang.org/grpc v1.75.0 // indirect
|
||||
google.golang.org/protobuf v1.36.8 // indirect
|
||||
google.golang.org/protobuf v1.36.10 // indirect
|
||||
gopkg.in/ini.v1 v1.67.2 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
149
go.sum
149
go.sum
@@ -1,9 +1,9 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
gitea.com/red-future/common v0.0.4 h1:2QgKc+B2iNfPRncKpmIqIzVwaMGJ3y3dt5v+35YD8SU=
|
||||
gitea.com/red-future/common v0.0.4/go.mod h1:UI9N5UUjilbMPF7+/lypZSnqDVHigt14300oSRrAyZg=
|
||||
gitea.redpowerfuture.com/red-future/common v0.0.23 h1:xieoA00iKOCDm5SO9iXn+cSyMKBAlZwI0fuEVPWrHLg=
|
||||
gitea.redpowerfuture.com/red-future/common v0.0.23/go.mod h1:50U1Xi+Ie56z09S5LQbZvaken0Mxv3OeS9LgR7U/ZRY=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg=
|
||||
github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
||||
github.com/BurntSushi/toml v1.6.0 h1:dRaEfpa2VI55EwlIW72hMRHdWouJeRF7TPYhI+AUQjk=
|
||||
github.com/BurntSushi/toml v1.6.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
||||
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
@@ -36,6 +36,8 @@ github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp
|
||||
github.com/clbanning/mxj/v2 v2.7.0 h1:WA/La7UGCanFe5NpHF0Q3DNtnCsVoxbPKuyBNHWRyME=
|
||||
github.com/clbanning/mxj/v2 v2.7.0/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/clipperhouse/uax29/v2 v2.7.0 h1:+gs4oBZ2gPfVrKPthwbMzWZDaAFPGYK72F0NJv2v7Vk=
|
||||
github.com/clipperhouse/uax29/v2 v2.7.0/go.mod h1:EFJ2TJMRUaplDxHKj1qAEhCtQPW2tJSwu5BF98AuoVM=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@@ -61,12 +63,12 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
|
||||
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
|
||||
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
|
||||
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
|
||||
github.com/fatih/color v1.19.0 h1:Zp3PiM21/9Ld6FzSKyL5c/BULoe/ONr9KlbYVOfG8+w=
|
||||
github.com/fatih/color v1.19.0/go.mod h1:zNk67I0ZUT1bEGsSGyCZYZNrHuTkJJB+r6Q9VuMi0LE=
|
||||
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
|
||||
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
||||
github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A=
|
||||
github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
|
||||
github.com/go-ego/gse v1.0.2 h1:+27lYFPhQEhA9igtdOsJPRKYL/k3TwYsxBF5jr6KFv4=
|
||||
github.com/go-ego/gse v1.0.2/go.mod h1:Fy35G+q7VV7Et1zIKO8o/sW1kkugV3znXap/lF/11zc=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
@@ -77,16 +79,16 @@ github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ4
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/gogf/gf/contrib/drivers/pgsql/v2 v2.10.0 h1:39+jbTenm7KBj4hO2C8ANAxVHpX/7OuRDs1VcGC9ylA=
|
||||
github.com/gogf/gf/contrib/drivers/pgsql/v2 v2.10.0/go.mod h1:B0s0fVzn0W220E8UTpSGzrrGKsop5KcB90twBeLCiz0=
|
||||
github.com/gogf/gf/contrib/nosql/redis/v2 v2.9.5 h1:Ku7p3CvGchxC7zPSgArf/tZs2w9Yb8tS/gH5ADN+p9g=
|
||||
github.com/gogf/gf/contrib/nosql/redis/v2 v2.9.5/go.mod h1:cjy18NsSLZQf5zaLAzuo7B2gr8GGjCTWDTEPY7T+6FI=
|
||||
github.com/gogf/gf/contrib/drivers/pgsql/v2 v2.10.2 h1:u8EpP24GkprogROnJ7htMov9Fc66pTP1eVYrWxiCYOs=
|
||||
github.com/gogf/gf/contrib/drivers/pgsql/v2 v2.10.2/go.mod h1:GmvM3r8GVByVMi4RD2+MCs5+CfxVXPMeT8mVDkAaAXE=
|
||||
github.com/gogf/gf/contrib/nosql/redis/v2 v2.10.2 h1:iTQegT+lEg/wDKvj2mi3W1wrdrwFarjokf88EXVVgu4=
|
||||
github.com/gogf/gf/contrib/nosql/redis/v2 v2.10.2/go.mod h1:ZRw3GNz5cq4uYrW4TPSVyrYWaoqzujKdWro/AOcGBaE=
|
||||
github.com/gogf/gf/contrib/registry/consul/v2 v2.9.5 h1:eUqwJ/qNH8lJ6yssiqskazgp1ACQuNU6zXlLOZVuXTQ=
|
||||
github.com/gogf/gf/contrib/registry/consul/v2 v2.9.5/go.mod h1:sjQyMry9+0POYZCA6lHXBxO77WoNKkruJpRB4xKqk5k=
|
||||
github.com/gogf/gf/contrib/trace/otlphttp/v2 v2.9.5 h1:tHUEZYB5GTqEYYVDYnlGobf1xISARKDE4KHVlgjwTec=
|
||||
github.com/gogf/gf/contrib/trace/otlphttp/v2 v2.9.5/go.mod h1:cfzTn2HS9RDX8f5pUVkbGxUWcSosouqfNQ1G6cY0V88=
|
||||
github.com/gogf/gf/v2 v2.10.0 h1:rzDROlyqGMe/eM6dCalSR8dZOuMIdLhmxKSH1DGhbFs=
|
||||
github.com/gogf/gf/v2 v2.10.0/go.mod h1:Svl1N+E8G/QshU2DUbh/3J/AJauqCgUnxHurXWR4Qx0=
|
||||
github.com/gogf/gf/v2 v2.10.2 h1:46IO0Uc8e85/FqdftJFskfDejJLBL0JBnGS5qOftUu8=
|
||||
github.com/gogf/gf/v2 v2.10.2/go.mod h1:Svl1N+E8G/QshU2DUbh/3J/AJauqCgUnxHurXWR4Qx0=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
@@ -130,8 +132,8 @@ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
|
||||
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo=
|
||||
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA=
|
||||
github.com/grokify/html-strip-tags-go v0.1.0 h1:03UrQLjAny8xci+R+qjCce/MYnpNXCtgzltlQbOBae4=
|
||||
github.com/grokify/html-strip-tags-go v0.1.0/go.mod h1:ZdzgfHEzAfz9X6Xe5eBLVblWIxXfYSQ40S/VKrAOGpc=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 h1:8Tjv8EJ+pM1xP8mK6egEbD1OgnVTyacbefKhmbLhIhU=
|
||||
@@ -169,8 +171,8 @@ github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b
|
||||
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
|
||||
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go-version v1.2.1 h1:zEfKbn2+PDgroKdiOzqiE8rsmLqU2uwi5PB5pBJ3TkI=
|
||||
github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/hashicorp/go-version v1.9.0 h1:CeOIz6k+LoN3qX9Z0tyQrPtiB1DFYRPfCIBtaXPSCnA=
|
||||
github.com/hashicorp/go-version v1.9.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c=
|
||||
github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
@@ -185,8 +187,8 @@ github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/u
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
|
||||
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
|
||||
github.com/klauspost/compress v1.18.6 h1:2jupLlAwFm95+YDR+NwD2MEfFO9d4z4Prjl1XXDjuao=
|
||||
github.com/klauspost/compress v1.18.6/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ=
|
||||
github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/klauspost/cpuid/v2 v2.2.11 h1:0OwqZRYI2rFrjS4kvkDnqJkKHdHaRnCm68/DY4OxRzU=
|
||||
github.com/klauspost/cpuid/v2 v2.2.11/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
|
||||
@@ -219,19 +221,19 @@ github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Ky
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
|
||||
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/mattn/go-runewidth v0.0.23 h1:7ykA0T0jkPpzSvMS5i9uoNn2Xy3R383f9HDx3RybWcw=
|
||||
github.com/mattn/go-runewidth v0.0.23/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
|
||||
github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
|
||||
github.com/miekg/dns v1.1.63 h1:8M5aAw6OMZfFXTT7K5V0Eu5YiiL8l7nUAkyN6C9YwaY=
|
||||
github.com/miekg/dns v1.1.63/go.mod h1:6NGHfjhpmr5lt3XPLuyfDJi5AXbNIPM9PY6H6sF1Nfs=
|
||||
github.com/minio/crc64nvme v1.1.0 h1:e/tAguZ+4cw32D+IO/8GSf5UVr9y+3eJcxZI2WOO/7Q=
|
||||
github.com/minio/crc64nvme v1.1.0/go.mod h1:eVfm2fAzLlxMdUGc0EEBGSMmPwmXD5XiNRpnu9J3bvg=
|
||||
github.com/minio/crc64nvme v1.1.1 h1:8dwx/Pz49suywbO+auHCBpCtlW1OfpcLN7wYgVR6wAI=
|
||||
github.com/minio/crc64nvme v1.1.1/go.mod h1:eVfm2fAzLlxMdUGc0EEBGSMmPwmXD5XiNRpnu9J3bvg=
|
||||
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
|
||||
github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
|
||||
github.com/minio/minio-go/v7 v7.0.97 h1:lqhREPyfgHTB/ciX8k2r8k0D93WaFqxbJX36UZq5occ=
|
||||
github.com/minio/minio-go/v7 v7.0.97/go.mod h1:re5VXuo0pwEtoNLsNuSr0RrLfT/MBtohwdaSmPPSRSk=
|
||||
github.com/minio/minio-go/v7 v7.2.0 h1:RCJM0R1XOsRs+A3x3UCaf3ZYbByDaLjFeAi+YCQEPhs=
|
||||
github.com/minio/minio-go/v7 v7.2.0/go.mod h1:EU9hENAStx/xXduNdrGO5e4X5vk19NtgB+RIPjZO8o0=
|
||||
github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI=
|
||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
@@ -275,13 +277,14 @@ github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8b
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
|
||||
github.com/r3labs/diff/v2 v2.15.1 h1:EOrVqPUzi+njlumoqJwiS/TgGgmZo83619FNDB9xQUg=
|
||||
github.com/r3labs/diff/v2 v2.15.1/go.mod h1:I8noH9Fc2fjSaMxqF3G2lhDdC0b+JXCfyx85tWFM9kc=
|
||||
github.com/redis/go-redis/v9 v9.12.1 h1:k5iquqv27aBtnTm2tIkROUDp8JBXhXZIVu1InSgvovg=
|
||||
github.com/redis/go-redis/v9 v9.12.1/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
||||
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
|
||||
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
|
||||
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
|
||||
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
||||
github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU=
|
||||
github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0=
|
||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
@@ -291,33 +294,40 @@ github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
github.com/tiger1103/gfast-token v1.0.10 h1:fNiBE/Dq5iTHvTGlCx3DmXa2o4hr0NtumFpffZ39k6s=
|
||||
github.com/tiger1103/gfast-token v1.0.10/go.mod h1:a/21mxmj7zFeNvjhZSC0XpEAFHfb1aT2k6DXnufFU1s=
|
||||
github.com/tinylib/msgp v1.3.0 h1:ULuf7GPooDaIlbyvgAxBV/FI7ynli6LZ1/nVUNu+0ww=
|
||||
github.com/tinylib/msgp v1.3.0/go.mod h1:ykjzy2wzgrlvpDCRc4LA8UXy6D8bzMSuAF3WD57Gok0=
|
||||
github.com/tinylib/msgp v1.6.1 h1:ESRv8eL3u+DNHUoSAAQRE50Hm162zqAnBoGv9PzScPY=
|
||||
github.com/tinylib/msgp v1.6.1/go.mod h1:RSp0LW9oSxFut3KzESt5Voq4GVWyS+PSulT77roAqEA=
|
||||
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
|
||||
github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY=
|
||||
github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4=
|
||||
github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8=
|
||||
github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM=
|
||||
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 h1:ilQV1hzziu+LLM3zUTJ0trRztfwgjqKnBWNtSRkbmwM=
|
||||
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78/go.mod h1:aL8wCCfTfSfmXjznFBSZNN13rSJjlIOI1fUNAtF7rmI=
|
||||
github.com/vcaesar/cedar v0.30.0 h1:9fSDpM7FTjjUdPiBUUa0MWYMRGSEcqgFXvppZcZ4d7Y=
|
||||
github.com/vcaesar/cedar v0.30.0/go.mod h1:lyuGvALuZZDPNXwpzv/9LyxW+8Y6faN7zauFezNsnik=
|
||||
github.com/vcaesar/tt v0.20.1 h1:D/jUeeVCNbq3ad8M7hhtB3J9x5RZ6I1n1eZ0BJp7M+4=
|
||||
github.com/vcaesar/tt v0.20.1/go.mod h1:cH2+AwGAJm19Wa6xvEa+0r+sXDJBT0QgNQey6mwqLeU=
|
||||
github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI=
|
||||
github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
go.mongodb.org/mongo-driver/v2 v2.4.1 h1:hGDMngUao03OVQ6sgV5csk+RWOIkF+CuLsTPobNMGNI=
|
||||
go.mongodb.org/mongo-driver/v2 v2.4.1/go.mod h1:jHeEDJHJq7tm6ZF45Issun9dbogjfnPySb1vXA7EeAI=
|
||||
github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ=
|
||||
github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0=
|
||||
github.com/zeebo/xxh3 v1.1.0 h1:s7DLGDK45Dyfg7++yxI0khrfwq9661w9EN78eP/UZVs=
|
||||
github.com/zeebo/xxh3 v1.1.0/go.mod h1:IisAie1LELR4xhVinxWS5+zf1lA4p0MW4T+w+W07F5s=
|
||||
go.mongodb.org/mongo-driver/v2 v2.4.0 h1:Oq6BmUAAFTzMeh6AonuDlgZMuAuEiUxoAD1koK5MuFo=
|
||||
go.mongodb.org/mongo-driver/v2 v2.4.0/go.mod h1:jHeEDJHJq7tm6ZF45Issun9dbogjfnPySb1vXA7EeAI=
|
||||
go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M=
|
||||
go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
||||
@@ -340,31 +350,32 @@ go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOV
|
||||
go.opentelemetry.io/proto/otlp v1.7.1/go.mod h1:b2rVh6rfI/s2pHWNlB7ILJcRALpcNDzKhACevjI+ZnE=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
|
||||
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
|
||||
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-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
|
||||
golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
|
||||
golang.org/x/crypto v0.51.0 h1:IBPXwPfKxY7cWQZ38ZCIRPI50YLeevDLlLnyC5wRGTI=
|
||||
golang.org/x/crypto v0.51.0/go.mod h1:8AdwkbraGNABw2kOX6YFPs3WM22XqI4EXEd8g+x7Oc8=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20250128144449-3edf0e91c1ae h1:COZdc9Ut6wLq7MO9GIYxfZl4n4ScmgqQLoHocKXrxco=
|
||||
golang.org/x/exp v0.0.0-20250128144449-3edf0e91c1ae/go.mod h1:tujkw807nyEEAamNbDrEGzRav+ilXA7PCRAd6xsmwiU=
|
||||
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 h1:nDVHiLt8aIbd/VzvPWN6kSOPE7+F/fNFDSXLVYkE/Iw=
|
||||
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394/go.mod h1:sIifuuw/Yco/y6yb6+bDNfyeQ/MdPUy/hKEMYQV17cM=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA=
|
||||
golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w=
|
||||
golang.org/x/mod v0.35.0 h1:Ww1D637e6Pg+Zb2KrWfHQUnH2dQRLBQyAtpr/haaJeM=
|
||||
golang.org/x/mod v0.35.0/go.mod h1:+GwiRhIInF8wPm+4AoT6L0FA1QWAad3OMdTRx4tFYlU=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
@@ -373,9 +384,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
|
||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
|
||||
golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
|
||||
golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA=
|
||||
golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@@ -384,9 +394,8 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
|
||||
golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
|
||||
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
|
||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@@ -405,27 +414,21 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/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-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
||||
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/sys v0.44.0 h1:ildZl3J4uzeKP07r2F++Op7E9B29JRUy+a27EibtBTQ=
|
||||
golang.org/x/sys v0.44.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/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.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
||||
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
|
||||
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
|
||||
golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc=
|
||||
golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
@@ -435,9 +438,8 @@ golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtn
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ=
|
||||
golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs=
|
||||
golang.org/x/tools v0.44.0 h1:UP4ajHPIcuMjT1GqzDWRlalUEoY+uzoZKnhOjbIPD2c=
|
||||
golang.org/x/tools v0.44.0/go.mod h1:KA0AfVErSdxRZIsOVipbv3rQhVXTnlU6UhKxHd1seDI=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
@@ -446,6 +448,9 @@ gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
|
||||
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
@@ -469,13 +474,15 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc=
|
||||
google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
|
||||
google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE=
|
||||
google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/ini.v1 v1.67.2 h1:JtOSMb9OuaCZKr7h5D/h6iii14sK0hLbplTc6frx4Ss=
|
||||
gopkg.in/ini.v1 v1.67.2/go.mod h1:x/cyOwCgZqOkJoDIJ3c1KNHMo10+nLGAhh+kn3Zizss=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
|
||||
4
main.go
4
main.go
@@ -6,8 +6,8 @@ import (
|
||||
"oss/service"
|
||||
"time"
|
||||
|
||||
"gitea.com/red-future/common/http"
|
||||
"gitea.com/red-future/common/jaeger"
|
||||
"gitea.redpowerfuture.com/red-future/common/http"
|
||||
"gitea.redpowerfuture.com/red-future/common/jaeger"
|
||||
_ "github.com/gogf/gf/contrib/drivers/pgsql/v2"
|
||||
_ "github.com/gogf/gf/contrib/nosql/redis/v2"
|
||||
"github.com/gogf/gf/v2/os/glog"
|
||||
|
||||
268
minio/minio.go
Normal file
268
minio/minio.go
Normal file
@@ -0,0 +1,268 @@
|
||||
package minio
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"gitea.redpowerfuture.com/red-future/common/utils"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
"github.com/gogf/gf/v2/os/glog"
|
||||
"github.com/google/uuid"
|
||||
"github.com/minio/minio-go/v7"
|
||||
"github.com/minio/minio-go/v7/pkg/credentials"
|
||||
)
|
||||
|
||||
// IoConfig 映射 YAML 中的 minio 配置节点
|
||||
type IoConfig struct {
|
||||
Endpoint string `yaml:"endpoint"` // MinIO API 地址
|
||||
AccessKey string `yaml:"accessKey"` // AK
|
||||
SecretKey string `yaml:"secretKey"` // SK
|
||||
Secure bool `yaml:"secure"` // 是否启用 SSL
|
||||
Region string `yaml:"region"` // 区域
|
||||
}
|
||||
|
||||
// 全局 MinIO 客户端(初始化一次,避免重复创建)
|
||||
var minioClient *minio.Client
|
||||
var minioCfg IoConfig
|
||||
|
||||
// initMinIO 初始化 MinIO 客户端。
|
||||
func init() {
|
||||
ctx := context.Background()
|
||||
if !g.Cfg().MustGet(ctx, "minio").IsEmpty() {
|
||||
// 加载 MinIO 配置(可从配置文件/环境变量读取,这里硬编码示例)
|
||||
minioCfg = IoConfig{
|
||||
Endpoint: g.Cfg().MustGet(ctx, "minio.endpoint").String(),
|
||||
AccessKey: g.Cfg().MustGet(ctx, "minio.accessKey").String(),
|
||||
SecretKey: g.Cfg().MustGet(ctx, "minio.secretKey").String(),
|
||||
Secure: g.Cfg().MustGet(ctx, "minio.secure").Bool(),
|
||||
Region: g.Cfg().MustGet(ctx, "minio.region").String(),
|
||||
}
|
||||
// 创建 MinIO 客户端
|
||||
var err error
|
||||
if minioClient, err = minio.New(minioCfg.Endpoint, &minio.Options{
|
||||
Creds: credentials.NewStaticV4(minioCfg.AccessKey, minioCfg.SecretKey, ""),
|
||||
Secure: minioCfg.Secure,
|
||||
Region: minioCfg.Region,
|
||||
}); err != nil {
|
||||
glog.Errorf(ctx, "初始化 MinIO 客户端失败: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ensureBucketAndObjectName 确保桶存在,并生成对象名
|
||||
// 返回: bucketName, objectName, fileFormat, error
|
||||
func ensureBucketAndObjectName(ctx context.Context, fileName string, fileStoreURL string) (string, string, string, error) {
|
||||
bucketName, err := utils.GetBucketName(ctx)
|
||||
if err != nil {
|
||||
glog.Errorf(ctx, "获取桶名称失败: %v", err)
|
||||
return "", "", "", err
|
||||
}
|
||||
// 检查/创建桶
|
||||
exists, err := minioClient.BucketExists(ctx, bucketName)
|
||||
if err != nil {
|
||||
glog.Errorf(ctx, "检查桶是否存在失败: %v", err)
|
||||
return "", "", "", err
|
||||
}
|
||||
if !exists {
|
||||
if err = minioClient.MakeBucket(ctx, bucketName, minio.MakeBucketOptions{Region: minioCfg.Region}); err != nil {
|
||||
glog.Errorf(ctx, "创建桶失败: %v", err)
|
||||
return "", "", "", err
|
||||
}
|
||||
glog.Infof(ctx, "成功创建 MinIO 桶: %s", bucketName)
|
||||
}
|
||||
// 生成对象名
|
||||
fileExt := filepath.Ext(fileName)
|
||||
uniqueID := uuid.New().String()[:32]
|
||||
timestamp := time.Now().Format("2006-01-02")
|
||||
objectName := fmt.Sprintf("/%s/%s%s", timestamp, uniqueID, fileExt)
|
||||
if fileStoreURL != "" {
|
||||
objectName = fmt.Sprintf("/%s/%s/%s%s", timestamp, fileStoreURL, uniqueID, fileExt)
|
||||
}
|
||||
// 设置存储桶公共读权限
|
||||
policy := `{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"AWS":["*"]},"Action":["s3:GetObject"],"Resource":["arn:aws:s3:::` + bucketName + `/*"]}]}`
|
||||
if err = minioClient.SetBucketPolicy(ctx, bucketName, policy); err != nil {
|
||||
glog.Errorf(ctx, "设置存储桶权限失败: %v", err)
|
||||
return "", "", "", err
|
||||
}
|
||||
return bucketName, objectName, strings.TrimPrefix(fileExt, "."), nil
|
||||
}
|
||||
|
||||
func UploadFile(ctx context.Context, fileHeader *ghttp.UploadFile) (imagesUrl string, fileName string, fileFormat string, err error) {
|
||||
bucketName, objectName, fileFormat, err := ensureBucketAndObjectName(ctx, fileHeader.Filename, "")
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
// 打开文件,获取 io.Reader(*os.File 实现了 io.Reader)
|
||||
file, err := fileHeader.Open()
|
||||
if err != nil {
|
||||
glog.Errorf(ctx, "打开文件失败: %v", err)
|
||||
return
|
||||
}
|
||||
defer file.Close() // 必须关闭,避免文件句柄泄露
|
||||
// 获取文件类型
|
||||
buffer := make([]byte, 512)
|
||||
_, err = file.Read(buffer)
|
||||
if err != nil {
|
||||
glog.Errorf(ctx, "读取文件头失败: %v", err)
|
||||
return
|
||||
}
|
||||
contentType := http.DetectContentType(buffer)
|
||||
// 重置文件读取位置,否则后续 PutObject 会从第512字节开始上传
|
||||
if _, err = file.Seek(0, 0); err != nil {
|
||||
glog.Errorf(ctx, "重置文件读取位置失败: %v", err)
|
||||
return
|
||||
}
|
||||
// 执行图片上传
|
||||
_, err = minioClient.PutObject(
|
||||
ctx,
|
||||
bucketName,
|
||||
objectName,
|
||||
file,
|
||||
fileHeader.Size,
|
||||
minio.PutObjectOptions{
|
||||
ContentType: contentType, // 关键:指定图片MIME类型,S3会根据此类型处理
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
glog.Errorf(ctx, "上传图片失败: %v", err)
|
||||
return
|
||||
}
|
||||
return objectName, fileHeader.Filename, fileFormat, nil
|
||||
}
|
||||
|
||||
// UploadFileBytes 直接上传字节流到 MinIO
|
||||
func UploadFileBytes(ctx context.Context, fileName string, fileBytes []byte, fileStoreURL string) (imagesUrl string, fileFormat string, err error) {
|
||||
bucketName, objectName, fileFormat, err := ensureBucketAndObjectName(ctx, fileName, fileStoreURL)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
// ============== 1. 强制从文件后缀获取 ContentType(绝对准确) ==============
|
||||
ext := strings.ToLower(filepath.Ext(fileName))
|
||||
contentType := "application/octet-stream" // 默认二进制流
|
||||
if t, ok := contentTypeMap[ext]; ok {
|
||||
contentType = t
|
||||
}
|
||||
|
||||
// ============== 2. 强制指定编码,解决 HTML 乱码 ==============
|
||||
putOpts := minio.PutObjectOptions{
|
||||
ContentType: contentType,
|
||||
// 强制存储为 utf-8,解决网页/文本乱码
|
||||
UserMetadata: map[string]string{
|
||||
"Charset": "UTF-8",
|
||||
},
|
||||
}
|
||||
// ====================== 核心修复 ======================
|
||||
// 1. 尝试解码 Base64(因为 JSON 传 []byte 会自动编码)
|
||||
var rawBytes []byte
|
||||
decodedBytes, decodeErr := base64.StdEncoding.DecodeString(string(fileBytes))
|
||||
if decodeErr == nil {
|
||||
// 解码成功 → 使用原始二进制(图片/HTML)
|
||||
rawBytes = decodedBytes
|
||||
} else {
|
||||
// 解码失败 → 直接使用原字节
|
||||
rawBytes = fileBytes
|
||||
}
|
||||
// 上传
|
||||
_, err = minioClient.PutObject(
|
||||
ctx,
|
||||
bucketName,
|
||||
objectName,
|
||||
bytes.NewReader(rawBytes),
|
||||
int64(len(rawBytes)),
|
||||
putOpts,
|
||||
)
|
||||
if err != nil {
|
||||
glog.Errorf(ctx, "上传文件失败: %v", err)
|
||||
return
|
||||
}
|
||||
return objectName, fileFormat, nil
|
||||
}
|
||||
|
||||
// 常见图片/HTML 类型映射
|
||||
var contentTypeMap = map[string]string{
|
||||
".jpg": "image/jpeg",
|
||||
".jpeg": "image/jpeg",
|
||||
".png": "image/png",
|
||||
".gif": "image/gif",
|
||||
".bmp": "image/bmp",
|
||||
".webp": "image/webp",
|
||||
".svg": "image/svg+xml",
|
||||
".html": "text/html",
|
||||
".htm": "text/html",
|
||||
}
|
||||
|
||||
func DownloadToFile(ctx context.Context, fileURL string, localPath string) (err error) {
|
||||
bucketName, err := utils.GetBucketName(ctx) // 桶名
|
||||
if err != nil {
|
||||
glog.Errorf(ctx, "获取桶名称失败: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
fileName := filepath.Base(fileURL)
|
||||
localPath = filepath.Join(localPath, fileName)
|
||||
|
||||
// 执行下载
|
||||
err = minioClient.FGetObject(
|
||||
ctx,
|
||||
bucketName,
|
||||
fileURL,
|
||||
localPath,
|
||||
minio.GetObjectOptions{}, // 可设置签名、加密等参数
|
||||
)
|
||||
if err != nil {
|
||||
fmt.Println("下载失败:", err)
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// DownloadToBrowser 下载文件到浏览器(返回文件流,由 HTTP Response 直接写出)
|
||||
// 参数 fileURL: MinIO 中的对象路径(即 objectName)
|
||||
// 返回: 文件字节流、文件名、ContentType、错误
|
||||
func DownloadToBrowser(ctx context.Context, fileURL string) (fileBytes []byte, fileName string, contentType string, err error) {
|
||||
bucketName, err := utils.GetBucketName(ctx)
|
||||
if err != nil {
|
||||
glog.Errorf(ctx, "获取桶名称失败: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// 获取对象流
|
||||
object, err := minioClient.GetObject(ctx, bucketName, fileURL, minio.GetObjectOptions{})
|
||||
if err != nil {
|
||||
glog.Errorf(ctx, "获取文件流失败: %v", err)
|
||||
return
|
||||
}
|
||||
defer object.Close()
|
||||
|
||||
// 获取对象元信息(用于读取 ContentType 和 Size)
|
||||
info, err := object.Stat()
|
||||
if err != nil {
|
||||
glog.Errorf(ctx, "获取文件信息失败: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// 读取全部内容
|
||||
fileBytes, err = io.ReadAll(object)
|
||||
if err != nil {
|
||||
glog.Errorf(ctx, "读取文件流失败: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// 提取文件名
|
||||
fileName = filepath.Base(fileURL)
|
||||
contentType = info.ContentType
|
||||
if contentType == "" {
|
||||
contentType = "application/octet-stream"
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
@@ -5,6 +5,18 @@ import (
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
)
|
||||
|
||||
type DownloadToFileReq struct {
|
||||
g.Meta `path:"/downloadToFile" method:"post" tags:"存储管理" summary:"下载文件到本地" dc:"下载文件到本地"`
|
||||
FileURL string `json:"fileURL" dc:"文件URL"`
|
||||
LocalPath string `json:"localPath" dc:"本地路径"`
|
||||
}
|
||||
|
||||
// DownloadToBrowserReq 下载文件到浏览器请求
|
||||
type DownloadToBrowserReq struct {
|
||||
g.Meta `path:"/downloadToBrowser" method:"post" tags:"存储管理" summary:"下载文件到浏览器" dc:"下载文件到浏览器"`
|
||||
FileURL string `json:"fileURL" dc:"文件URL" in:"query"`
|
||||
}
|
||||
|
||||
// UploadFileReq 上传文件请求
|
||||
type UploadFileReq struct {
|
||||
g.Meta `path:"/uploadFile" method:"post" tags:"存储管理" summary:"上传文件" dc:"上传文件"`
|
||||
@@ -20,5 +32,16 @@ type UploadFile struct {
|
||||
// UploadFileRes 上传文件响应
|
||||
type UploadFileRes struct {
|
||||
FileURL string `json:"fileURL" dc:"上传地址"`
|
||||
FileSize int `json:"fileSize" dc:"文件大小"`
|
||||
FileName string `json:"fileName" dc:"文件名称"`
|
||||
FileFormat string `json:"fileFormat" dc:"文件格式"`
|
||||
FileAddressPrefix string `json:"fileAddressPrefix"`
|
||||
}
|
||||
|
||||
// UploadFileBytesReq 上传文件请求(字节流)
|
||||
type UploadFileBytesReq struct {
|
||||
g.Meta `path:"/uploadFileBytes" method:"post" tags:"存储管理" summary:"上传文件(字节流)" dc:"上传文件(字节流)"`
|
||||
FileName string `json:"fileName" dc:"文件名"`
|
||||
FileBytes []byte `json:"fileBytes" dc:"文件字节流"`
|
||||
FileStoreURL string `json:"fileStoreURL" dc:"文件存储的URL"`
|
||||
}
|
||||
|
||||
@@ -1,28 +1,25 @@
|
||||
package entity
|
||||
|
||||
import (
|
||||
"gitea.com/red-future/common/beans"
|
||||
"gitea.redpowerfuture.com/red-future/common/beans"
|
||||
)
|
||||
|
||||
// File 存储文件实体
|
||||
type File struct {
|
||||
beans.SQLBaseDO `orm:",inherit"` // 嵌入基础字段:Id, Bid, Creator, CreatedAt, Updater, UpdatedAt, Deleter, DeletedAt, IsDeleted
|
||||
// 业务字段
|
||||
TenantId uint64 `orm:"tenant_id" json:"tenantId"` // 租户ID
|
||||
FileURL string `orm:"file_url" json:"fileURL"` // 文件URL
|
||||
FileURL string `orm:"file_url" json:"fileURL"` // 文件URL
|
||||
FileSize int `orm:"file_size" json:"fileSize"`
|
||||
}
|
||||
|
||||
type fileCol struct {
|
||||
beans.SQLBaseCol
|
||||
TenantId string
|
||||
FileURL string
|
||||
FileSize string
|
||||
}
|
||||
|
||||
var FileCol = fileCol{
|
||||
SQLBaseCol: beans.DefSQLBaseCol,
|
||||
TenantId: "tenant_id",
|
||||
FileURL: "file_url",
|
||||
FileSize: "file_size",
|
||||
}
|
||||
|
||||
@@ -1,28 +1,25 @@
|
||||
package entity
|
||||
|
||||
import (
|
||||
"gitea.com/red-future/common/beans"
|
||||
"gitea.redpowerfuture.com/red-future/common/beans"
|
||||
)
|
||||
|
||||
// TenantOssTotal 租户储存服务总计实体
|
||||
type TenantOssTotal struct {
|
||||
beans.SQLBaseDO `orm:",inherit"` // 嵌入基础字段:Id, Creator, CreatedAt, Updater, UpdatedAt, TenantId, IsDeleted
|
||||
// 基础信息
|
||||
TenantId uint64 `orm:"tenant_id" json:"tenantId"` // 租户ID
|
||||
UsedOssSize int `orm:"used_oss_size" json:"usedOssSize"`
|
||||
TotalOssSize int `orm:"total_oss_size" json:"totalOssSize"`
|
||||
UsedOssSize int `orm:"used_oss_size" json:"usedOssSize"`
|
||||
TotalOssSize int `orm:"total_oss_size" json:"totalOssSize"`
|
||||
}
|
||||
|
||||
type tenantOssCol struct {
|
||||
beans.SQLBaseCol
|
||||
TenantId string
|
||||
UsedOssSize string
|
||||
TotalOssSize string
|
||||
}
|
||||
|
||||
var TenantOssCol = tenantOssCol{
|
||||
SQLBaseCol: beans.DefSQLBaseCol,
|
||||
TenantId: "tenant_id",
|
||||
UsedOssSize: "used_oss_size",
|
||||
TotalOssSize: "total_oss_size",
|
||||
}
|
||||
|
||||
@@ -3,17 +3,18 @@ package service
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"oss/consts"
|
||||
"oss/dao"
|
||||
"oss/minio"
|
||||
"oss/model/dto"
|
||||
"oss/model/entity"
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/v2/net/ghttp"
|
||||
"github.com/gogf/gf/v2/os/glog"
|
||||
|
||||
"gitea.com/red-future/common/minio"
|
||||
"gitea.com/red-future/common/redis"
|
||||
"gitea.com/red-future/common/utils"
|
||||
"gitea.redpowerfuture.com/red-future/common/utils"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
@@ -24,6 +25,27 @@ type file struct{}
|
||||
// File 存储文件服务
|
||||
var File = new(file)
|
||||
|
||||
func (f *file) DownloadToFile(ctx context.Context, req *dto.DownloadToFileReq) (err error) {
|
||||
return minio.DownloadToFile(ctx, req.FileURL, req.LocalPath)
|
||||
}
|
||||
|
||||
// DownloadToBrowser 下载文件到浏览器
|
||||
func (f *file) DownloadToBrowser(ctx context.Context, req *dto.DownloadToBrowserReq) (err error) {
|
||||
fileBytes, fileName, contentType, err := minio.DownloadToBrowser(ctx, req.FileURL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
r := ghttp.RequestFromCtx(ctx)
|
||||
// 设置响应头
|
||||
r.Response.Header().Set("Content-Type", contentType)
|
||||
r.Response.Header().Set("Content-Disposition", fmt.Sprintf(`attachment; filename="%s"; filename*=UTF-8''%s`, fileName, url.PathEscape(fileName)))
|
||||
r.Response.Header().Set("Content-Length", fmt.Sprintf("%d", len(fileBytes)))
|
||||
// 写出二进制流
|
||||
r.Response.Write(fileBytes)
|
||||
return
|
||||
}
|
||||
|
||||
func (f *file) UploadFile(ctx context.Context, req *dto.UploadFileReq) (res *dto.UploadFileRes, err error) {
|
||||
fileSize := gconv.Int(req.File.Size)
|
||||
totalFileSize := 0
|
||||
@@ -39,9 +61,9 @@ func (f *file) UploadFile(ctx context.Context, req *dto.UploadFileReq) (res *dto
|
||||
// 获取redis-租户存储-锁key
|
||||
fileLockKey := fmt.Sprintf(consts.FileLockKey, gconv.String(user.TenantId))
|
||||
|
||||
success, err := redis.Lock(ctx, fileLockKey, gconv.Int64(time.Minute*1), func(ctx context.Context) error {
|
||||
success, err := utils.Lock(ctx, fileLockKey, gconv.Int64(time.Minute*1), func(ctx context.Context) error {
|
||||
// 获取redis-租户存储容量总数
|
||||
get, err := redis.RedisClient().Get(ctx, tenantOssTotalKey)
|
||||
get, err := g.Redis().Get(ctx, tenantOssTotalKey)
|
||||
if err != nil {
|
||||
glog.Errorf(ctx, "获取redis-租户存储容量总数失败: %v", err)
|
||||
return err
|
||||
@@ -84,7 +106,7 @@ func (f *file) UploadFile(ctx context.Context, req *dto.UploadFileReq) (res *dto
|
||||
Updater: user.UserName,
|
||||
}
|
||||
// 修改redis-租户存储容量总数 超时时间10分钟
|
||||
if err = redis.RedisClient().SetEX(ctx, tenantOssTotalKey, tenantOssTotalKeyMap, gconv.Int64(time.Minute*10)); err != nil {
|
||||
if err = g.Redis().SetEX(ctx, tenantOssTotalKey, tenantOssTotalKeyMap, gconv.Int64(time.Minute*10)); err != nil {
|
||||
glog.Errorf(ctx, "修改redis-租户存储容量总数 超时时间10分钟失败: %v", err)
|
||||
return err
|
||||
}
|
||||
@@ -100,7 +122,8 @@ func (f *file) UploadFile(ctx context.Context, req *dto.UploadFileReq) (res *dto
|
||||
return nil, gerror.New("存储服务内存不足")
|
||||
}
|
||||
// 上传图片
|
||||
fileURL, err := minio.UploadFile(ctx, req.File)
|
||||
var fileURL, fileName, fileFormat string
|
||||
fileURL, fileName, fileFormat, err = minio.UploadFile(ctx, req.File)
|
||||
if err != nil {
|
||||
glog.Errorf(ctx, "上传图片失败: %v", err)
|
||||
return nil, err
|
||||
@@ -115,8 +138,53 @@ func (f *file) UploadFile(ctx context.Context, req *dto.UploadFileReq) (res *dto
|
||||
return nil, err
|
||||
}
|
||||
// 返回图片url
|
||||
return &dto.UploadFileRes{
|
||||
FileURL: fileURL,
|
||||
FileAddressPrefix: minio.GetFileAddressPrefix(ctx),
|
||||
}, err
|
||||
res = &dto.UploadFileRes{
|
||||
FileURL: fileURL,
|
||||
FileSize: fileSize,
|
||||
FileName: fileName,
|
||||
FileFormat: fileFormat,
|
||||
}
|
||||
url, err := utils.GetFileAddressPrefix(ctx)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
res.FileAddressPrefix = url
|
||||
return
|
||||
}
|
||||
|
||||
// UploadFileBytes 上传文件(字节流)
|
||||
func (f *file) UploadFileBytes(ctx context.Context, req *dto.UploadFileBytesReq) (res *dto.UploadFileRes, err error) {
|
||||
// 获取用户信息
|
||||
user, err := utils.GetUserInfo(ctx)
|
||||
if err != nil {
|
||||
glog.Errorf(ctx, "获取用户信息失败: %v", err)
|
||||
return
|
||||
}
|
||||
tenantId := user.TenantId
|
||||
|
||||
// 上传到 MinIO
|
||||
fileURL, fileFormat, err := minio.UploadFileBytes(ctx, req.FileName, req.FileBytes, req.FileStoreURL)
|
||||
if err != nil {
|
||||
glog.Errorf(ctx, "上传文件失败: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 插入数据库记录
|
||||
ossEntity := &dto.UploadFile{
|
||||
TenantId: tenantId,
|
||||
FileURL: fileURL,
|
||||
FileSize: len(req.FileBytes),
|
||||
}
|
||||
if _, err = dao.File.Insert(ctx, ossEntity); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res = &dto.UploadFileRes{
|
||||
FileURL: fileURL,
|
||||
FileSize: len(req.FileBytes),
|
||||
FileName: req.FileName,
|
||||
FileFormat: fileFormat,
|
||||
}
|
||||
res.FileAddressPrefix, _ = utils.GetFileAddressPrefix(ctx)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -6,8 +6,7 @@ import (
|
||||
"oss/dao"
|
||||
"oss/model/dto"
|
||||
|
||||
"gitea.com/red-future/common/beans"
|
||||
"gitea.com/red-future/common/redis"
|
||||
"gitea.redpowerfuture.com/red-future/common/beans"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/util/gconv"
|
||||
)
|
||||
@@ -22,7 +21,7 @@ func (s *tenantOssTotal) UpdateUsedOssSize(ctx context.Context) (err error) {
|
||||
UserName: "admin",
|
||||
})
|
||||
// 使用 Keys 取出所有key
|
||||
keys, err := redis.RedisClient().Keys(ctx, consts.OssTotalKey)
|
||||
keys, err := g.Redis().Keys(ctx, consts.OssTotalKey)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@@ -40,10 +39,12 @@ func (s *tenantOssTotal) UpdateUsedOssSize(ctx context.Context) (err error) {
|
||||
updateData = append(updateData, e)
|
||||
|
||||
}
|
||||
// 更新数据库
|
||||
_, err = dao.TenantOssTotal.SaveOrUpdate(ctx, updateData)
|
||||
if err != nil {
|
||||
return err
|
||||
if len(updateData) != 0 {
|
||||
// 更新数据库
|
||||
_, err = dao.TenantOssTotal.SaveOrUpdate(ctx, updateData)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
61
update.sql
61
update.sql
@@ -1,9 +1,9 @@
|
||||
-----------张斌2025-06-16 15:00:00--------------
|
||||
|
||||
--------------------pgsql创建file表语句---------------------------
|
||||
--------------------pgsql创建oss_file表语句---------------------------
|
||||
|
||||
-- 存储文件表
|
||||
CREATE TABLE IF NOT EXISTS file (
|
||||
CREATE TABLE IF NOT EXISTS oss_file (
|
||||
-- 基础字段
|
||||
id BIGINT PRIMARY KEY,
|
||||
creator VARCHAR(64) NOT NULL,
|
||||
@@ -18,27 +18,26 @@ CREATE TABLE IF NOT EXISTS file (
|
||||
file_size INT NOT NULL DEFAULT 0
|
||||
);
|
||||
-- 为文件表添加索引
|
||||
CREATE INDEX idx_file_tenant_id ON file(tenant_id);
|
||||
CREATE INDEX idx_file_file_size ON file(file_size);
|
||||
CREATE INDEX idx_file_tenant_id ON oss_file(tenant_id);
|
||||
CREATE INDEX idx_file_file_size ON oss_file(file_size);
|
||||
|
||||
-- 文件表字段注释
|
||||
COMMENT ON TABLE file IS '存储文件表';
|
||||
COMMENT ON COLUMN file.id IS '主键ID';
|
||||
COMMENT ON COLUMN file.creator IS '创建人';
|
||||
COMMENT ON COLUMN file.created_at IS '创建时间';
|
||||
COMMENT ON COLUMN file.updater IS '更新人';
|
||||
COMMENT ON COLUMN file.updated_at IS '更新时间';
|
||||
COMMENT ON COLUMN file.deleted_at IS '删除时间(软删)';
|
||||
COMMENT ON COLUMN file.tenant_id IS '租户ID';
|
||||
COMMENT ON COLUMN file.file_url IS '文件URL';
|
||||
COMMENT ON COLUMN file.file_size IS '文件大小(字节)';
|
||||
COMMENT ON TABLE oss_file IS '存储文件表';
|
||||
COMMENT ON COLUMN oss_file.id IS '主键ID';
|
||||
COMMENT ON COLUMN oss_file.creator IS '创建人';
|
||||
COMMENT ON COLUMN oss_file.created_at IS '创建时间';
|
||||
COMMENT ON COLUMN oss_file.updater IS '更新人';
|
||||
COMMENT ON COLUMN oss_file.updated_at IS '更新时间';
|
||||
COMMENT ON COLUMN oss_file.deleted_at IS '删除时间(软删)';
|
||||
COMMENT ON COLUMN oss_file.tenant_id IS '租户ID';
|
||||
COMMENT ON COLUMN oss_file.file_url IS '文件URL';
|
||||
COMMENT ON COLUMN oss_file.file_size IS '文件大小(字节)';
|
||||
|
||||
--------------------pgsql创建file表语句---------------------------
|
||||
--------------------pgsql创建oss_file表语句---------------------------
|
||||
|
||||
|
||||
--------------------pgsql创建tenant_oss_total表语句---------------------------
|
||||
--------------------pgsql创建oss_tenant_oss_total表语句---------------------------
|
||||
-- 租户存储服务总计表
|
||||
CREATE TABLE IF NOT EXISTS tenant_oss_total (
|
||||
CREATE TABLE IF NOT EXISTS oss_tenant_oss_total (
|
||||
-- 基础字段
|
||||
id BIGINT PRIMARY KEY, -- 保留id作为主键
|
||||
creator VARCHAR(64) NOT NULL,
|
||||
@@ -57,19 +56,19 @@ CREATE TABLE IF NOT EXISTS tenant_oss_total (
|
||||
);
|
||||
|
||||
-- 为租户存储表添加索引
|
||||
CREATE INDEX idx_tenant_oss_total_used_size ON tenant_oss_total(used_oss_size);
|
||||
CREATE INDEX idx_tenant_oss_total_total_size ON tenant_oss_total(total_oss_size);
|
||||
CREATE INDEX idx_tenant_oss_total_used_size ON oss_tenant_oss_total(used_oss_size);
|
||||
CREATE INDEX idx_tenant_oss_total_total_size ON oss_tenant_oss_total(total_oss_size);
|
||||
|
||||
-- 租户存储表字段注释
|
||||
COMMENT ON TABLE tenant_oss_total IS '租户存储服务总计表';
|
||||
COMMENT ON COLUMN tenant_oss_total.id IS '主键ID';
|
||||
COMMENT ON COLUMN tenant_oss_total.creator IS '创建人';
|
||||
COMMENT ON COLUMN tenant_oss_total.created_at IS '创建时间';
|
||||
COMMENT ON COLUMN tenant_oss_total.updater IS '更新人';
|
||||
COMMENT ON COLUMN tenant_oss_total.updated_at IS '更新时间';
|
||||
COMMENT ON COLUMN tenant_oss_total.deleted_at IS '删除时间(软删)';
|
||||
COMMENT ON COLUMN tenant_oss_total.tenant_id IS '租户ID(唯一)';
|
||||
COMMENT ON COLUMN tenant_oss_total.used_oss_size IS '已使用存储大小(字节)';
|
||||
COMMENT ON COLUMN tenant_oss_total.total_oss_size IS '总存储大小(字节)';
|
||||
COMMENT ON TABLE oss_tenant_oss_total IS '租户存储服务总计表';
|
||||
COMMENT ON COLUMN oss_tenant_oss_total.id IS '主键ID';
|
||||
COMMENT ON COLUMN oss_tenant_oss_total.creator IS '创建人';
|
||||
COMMENT ON COLUMN oss_tenant_oss_total.created_at IS '创建时间';
|
||||
COMMENT ON COLUMN oss_tenant_oss_total.updater IS '更新人';
|
||||
COMMENT ON COLUMN oss_tenant_oss_total.updated_at IS '更新时间';
|
||||
COMMENT ON COLUMN oss_tenant_oss_total.deleted_at IS '删除时间(软删)';
|
||||
COMMENT ON COLUMN oss_tenant_oss_total.tenant_id IS '租户ID(唯一)';
|
||||
COMMENT ON COLUMN oss_tenant_oss_total.used_oss_size IS '已使用存储大小(字节)';
|
||||
COMMENT ON COLUMN oss_tenant_oss_total.total_oss_size IS '总存储大小(字节)';
|
||||
|
||||
--------------------pgsql创建tenant_oss_total表语句---------------------------
|
||||
--------------------pgsql创建oss_tenant_oss_total表语句---------------------------
|
||||
Reference in New Issue
Block a user