diff --git a/go.mod b/go.mod index 13bbba9..3f8b414 100644 --- a/go.mod +++ b/go.mod @@ -2,49 +2,134 @@ module kra go 1.24.6 +toolchain go1.24.7 + require ( entgo.io/ent v0.14.5 + github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible + github.com/aws/aws-sdk-go-v2 v1.41.0 + github.com/aws/aws-sdk-go-v2/config v1.32.6 + github.com/aws/aws-sdk-go-v2/credentials v1.19.6 + github.com/aws/aws-sdk-go-v2/service/s3 v1.95.0 + github.com/casbin/casbin/v2 v2.103.0 + github.com/casbin/gorm-adapter/v3 v3.32.0 github.com/go-kratos/aip-go/ents v0.0.0-20251213081434-74ffa1fc1588 github.com/go-kratos/kratos/v2 v2.8.0 - github.com/go-sql-driver/mysql v1.9.3 - github.com/golang-jwt/jwt/v5 v5.1.0 + github.com/go-sql-driver/mysql v1.8.1 + github.com/golang-jwt/jwt/v5 v5.2.2 github.com/google/uuid v1.6.0 github.com/google/wire v0.6.0 - go.einride.tech/aip v0.76.0 - go.uber.org/automaxprocs v1.5.1 + github.com/huaweicloud/huaweicloud-sdk-go-obs v3.24.9+incompatible + github.com/minio/minio-go/v7 v7.0.84 + github.com/mojocn/base64Captcha v1.3.8 + github.com/qiniu/go-sdk/v7 v7.25.2 + github.com/redis/go-redis/v9 v9.7.0 + github.com/robfig/cron/v3 v3.0.1 + github.com/tencentyun/cos-go-sdk-v5 v0.7.60 + go.einride.tech/aip v0.78.0 + go.uber.org/automaxprocs v1.6.0 google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2 google.golang.org/grpc v1.74.2 google.golang.org/protobuf v1.36.10 + gorm.io/driver/mysql v1.5.7 + gorm.io/driver/postgres v1.5.11 + gorm.io/driver/sqlite v1.6.0 + gorm.io/gorm v1.30.0 ) require ( ariga.io/atlas v0.32.1-0.20250325101103-175b25e1c1b9 // indirect dario.cat/mergo v1.0.0 // indirect filippo.io/edwards25519 v1.1.0 // indirect + github.com/BurntSushi/toml v1.3.2 // indirect github.com/agext/levenshtein v1.2.3 // indirect + github.com/alex-ant/gomath v0.0.0-20160516115720-89013a210a82 // indirect github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect + github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.4 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.16 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.16 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.16 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 // indirect + github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.16 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.7 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.16 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.16 // indirect + github.com/aws/aws-sdk-go-v2/service/signin v1.0.4 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.30.8 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.12 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.41.5 // indirect + github.com/aws/smithy-go v1.24.0 // indirect github.com/bmatcuk/doublestar v1.3.4 // indirect + github.com/bmatcuk/doublestar/v4 v4.6.1 // indirect + github.com/casbin/govaluate v1.3.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/clbanning/mxj v1.8.4 // indirect + github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect + github.com/dustin/go-humanize v1.0.1 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/gammazero/toposort v0.1.1 // indirect + github.com/glebarez/go-sqlite v1.21.2 // indirect + github.com/glebarez/sqlite v1.11.0 // indirect + github.com/go-ini/ini v1.67.0 // indirect github.com/go-kratos/aegis v0.2.0 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/inflect v0.19.0 // indirect - github.com/go-playground/form/v4 v4.2.1 // indirect + github.com/go-playground/form/v4 v4.2.0 // indirect + github.com/goccy/go-json v0.10.4 // indirect + github.com/gofrs/flock v0.8.1 // indirect + github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect + github.com/golang-sql/sqlexp v0.1.0 // indirect + github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect github.com/google/go-cmp v0.7.0 // indirect + github.com/google/go-querystring v1.0.0 // indirect github.com/gorilla/mux v1.8.1 // indirect github.com/hashicorp/hcl/v2 v2.18.1 // indirect + github.com/jackc/pgpassfile v1.0.0 // indirect + github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect + github.com/jackc/pgx/v5 v5.5.5 // indirect + github.com/jackc/puddle/v2 v2.2.1 // indirect + github.com/jinzhu/inflection v1.0.0 // indirect + github.com/jinzhu/now v1.1.5 // indirect + github.com/klauspost/compress v1.17.11 // indirect + github.com/klauspost/cpuid/v2 v2.2.9 // indirect + github.com/mattn/go-isatty v0.0.17 // indirect + github.com/mattn/go-sqlite3 v1.14.22 // indirect + github.com/microsoft/go-mssqldb v1.6.0 // indirect + github.com/minio/md5-simd v1.1.2 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect + github.com/mozillazg/go-httpheader v0.2.1 // indirect + github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect + github.com/richardlehane/mscfb v1.0.4 // indirect + github.com/richardlehane/msoleps v1.0.4 // indirect + github.com/rs/xid v1.6.0 // indirect + github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d // indirect + github.com/xuri/excelize/v2 v2.9.0 // indirect + github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7 // indirect github.com/zclconf/go-cty v1.14.4 // indirect github.com/zclconf/go-cty-yaml v1.1.0 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect go.opentelemetry.io/otel v1.36.0 // indirect go.opentelemetry.io/otel/metric v1.36.0 // indirect go.opentelemetry.io/otel/trace v1.36.0 // indirect + golang.org/x/crypto v0.38.0 // indirect + golang.org/x/image v0.23.0 // indirect golang.org/x/mod v0.23.0 // indirect golang.org/x/net v0.40.0 // indirect golang.org/x/sync v0.14.0 // indirect golang.org/x/sys v0.33.0 // indirect golang.org/x/text v0.25.0 // indirect + golang.org/x/time v0.14.0 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20251124214823-79d6a2a48846 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect + gorm.io/driver/sqlserver v1.5.3 // indirect + gorm.io/plugin/dbresolver v1.6.2 // indirect + modernc.org/fileutil v1.0.0 // indirect + modernc.org/libc v1.22.5 // indirect + modernc.org/mathutil v1.5.0 // indirect + modernc.org/memory v1.5.0 // indirect + modernc.org/sqlite v1.23.1 // indirect ) diff --git a/go.sum b/go.sum index dbd0755..df61463 100644 --- a/go.sum +++ b/go.sum @@ -8,18 +8,106 @@ entgo.io/ent v0.14.5 h1:Rj2WOYJtCkWyFo6a+5wB3EfBRP0rnx1fMk6gGA0UUe4= entgo.io/ent v0.14.5/go.mod h1:zTzLmWtPvGpmSwtkaayM2cm5m819NdM7z7tYPq3vN0U= filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.4.0/go.mod h1:ON4tFdPTwRcgWEaVDrN3584Ef+b7GgSJaXxe5fW9t4M= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.0/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.1/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.1 h1:/iHxaJhsFr0+xVFfbMr5vxz848jyiWuIEDhYq3y5odY= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.1/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0 h1:vcYCAze6p19qBW7MhZybIsqD8sMV8js0NyQM8JDnVtg= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0/go.mod h1:OQeznEEkTZ9OrhHJoDD8ZDq51FHgXjqtP9z6bEwBq9U= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.1.2/go.mod h1:eWRD7oawr1Mu1sLCawqVc0CUiF43ia3qQMxLscsKQ9w= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.2.0/go.mod h1:eWRD7oawr1Mu1sLCawqVc0CUiF43ia3qQMxLscsKQ9w= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 h1:sXr+ck84g/ZlZUOZiNELInmMgOsuGwdjjVkEIde0OtY= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0/go.mod h1:okt5dMMTOFjX/aovMlrjvvXoPMBVSPzk9185BT0+eZM= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.0.0 h1:yfJe15aSwEQ6Oo6J+gdfdulPNoZ3TEhmbhLIoxZcA+U= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.0.0/go.mod h1:Q28U+75mpCaSCDowNEmhIo/rmgdkqmkmzI7N6TGR4UY= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v0.8.0 h1:T028gtTPiYt/RMUfs8nVsAL7FDQrfLlrm/NnRG/zcC4= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v0.8.0/go.mod h1:cw4zVQgBby0Z5f2v0itn6se2dDP17nTjbZFXW5uPyHA= +github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0/go.mod h1:kgDmCTgBzIEPFElEF+FK0SdjAor06dRq2Go927dnQ6o= +github.com/AzureAD/microsoft-authentication-library-for-go v1.1.0 h1:HCc0+LpPfpCKs6LGGLAhwBARt9632unrVcI6i8s/8os= +github.com/AzureAD/microsoft-authentication-library-for-go v1.1.0/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= +github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= +github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= +github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM= github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= +github.com/alex-ant/gomath v0.0.0-20160516115720-89013a210a82 h1:7dONQ3WNZ1zy960TmkxJPuwoolZwL7xKtpcM04MBnt4= +github.com/alex-ant/gomath v0.0.0-20160516115720-89013a210a82/go.mod h1:nLnM0KdK1CmygvjpDUO6m1TjSsiQtL61juhNsvV/JVI= +github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible h1:8psS8a+wKfiLt1iVDX79F7Y6wUM49Lcha2FMXt4UM8g= +github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY= github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4= +github.com/aws/aws-sdk-go-v2 v1.41.0 h1:tNvqh1s+v0vFYdA1xq0aOJH+Y5cRyZ5upu6roPgPKd4= +github.com/aws/aws-sdk-go-v2 v1.41.0/go.mod h1:MayyLB8y+buD9hZqkCW3kX1AKq07Y5pXxtgB+rRFhz0= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.4 h1:489krEF9xIGkOaaX3CE/Be2uWjiXrkCH6gUX+bZA/BU= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.4/go.mod h1:IOAPF6oT9KCsceNTvvYMNHy0+kMF8akOjeDvPENWxp4= +github.com/aws/aws-sdk-go-v2/config v1.32.6 h1:hFLBGUKjmLAekvi1evLi5hVvFQtSo3GYwi+Bx4lpJf8= +github.com/aws/aws-sdk-go-v2/config v1.32.6/go.mod h1:lcUL/gcd8WyjCrMnxez5OXkO3/rwcNmvfno62tnXNcI= +github.com/aws/aws-sdk-go-v2/credentials v1.19.6 h1:F9vWao2TwjV2MyiyVS+duza0NIRtAslgLUM0vTA1ZaE= +github.com/aws/aws-sdk-go-v2/credentials v1.19.6/go.mod h1:SgHzKjEVsdQr6Opor0ihgWtkWdfRAIwxYzSJ8O85VHY= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.16 h1:80+uETIWS1BqjnN9uJ0dBUaETh+P1XwFy5vwHwK5r9k= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.16/go.mod h1:wOOsYuxYuB/7FlnVtzeBYRcjSRtQpAW0hCP7tIULMwo= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.16 h1:rgGwPzb82iBYSvHMHXc8h9mRoOUBZIGFgKb9qniaZZc= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.16/go.mod h1:L/UxsGeKpGoIj6DxfhOWHWQ/kGKcd4I1VncE4++IyKA= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.16 h1:1jtGzuV7c82xnqOVfx2F0xmJcOw5374L7N6juGW6x6U= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.16/go.mod h1:M2E5OQf+XLe+SZGmmpaI2yy+J326aFf6/+54PoxSANc= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 h1:WKuaxf++XKWlHWu9ECbMlha8WOEGm0OUEZqm4K/Gcfk= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4/go.mod h1:ZWy7j6v1vWGmPReu0iSGvRiise4YI5SkR3OHKTZ6Wuc= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.16 h1:CjMzUs78RDDv4ROu3JnJn/Ig1r6ZD7/T2DXLLRpejic= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.16/go.mod h1:uVW4OLBqbJXSHJYA9svT9BluSvvwbzLQ2Crf6UPzR3c= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4 h1:0ryTNEdJbzUCEWkVXEXoqlXV72J5keC1GvILMOuD00E= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.4/go.mod h1:HQ4qwNZh32C3CBeO6iJLQlgtMzqeG17ziAA/3KDJFow= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.7 h1:DIBqIrJ7hv+e4CmIk2z3pyKT+3B6qVMgRsawHiR3qso= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.7/go.mod h1:vLm00xmBke75UmpNvOcZQ/Q30ZFjbczeLFqGx5urmGo= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.16 h1:oHjJHeUy0ImIV0bsrX0X91GkV5nJAyv1l1CC9lnO0TI= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.16/go.mod h1:iRSNGgOYmiYwSCXxXaKb9HfOEj40+oTKn8pTxMlYkRM= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.16 h1:NSbvS17MlI2lurYgXnCOLvCFX38sBW4eiVER7+kkgsU= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.16/go.mod h1:SwT8Tmqd4sA6G1qaGdzWCJN99bUmPGHfRwwq3G5Qb+A= +github.com/aws/aws-sdk-go-v2/service/s3 v1.95.0 h1:MIWra+MSq53CFaXXAywB2qg9YvVZifkk6vEGl/1Qor0= +github.com/aws/aws-sdk-go-v2/service/s3 v1.95.0/go.mod h1:79S2BdqCJpScXZA2y+cpZuocWsjGjJINyXnOsf5DTz8= +github.com/aws/aws-sdk-go-v2/service/signin v1.0.4 h1:HpI7aMmJ+mm1wkSHIA2t5EaFFv5EFYXePW30p1EIrbQ= +github.com/aws/aws-sdk-go-v2/service/signin v1.0.4/go.mod h1:C5RdGMYGlfM0gYq/tifqgn4EbyX99V15P2V3R+VHbQU= +github.com/aws/aws-sdk-go-v2/service/sso v1.30.8 h1:aM/Q24rIlS3bRAhTyFurowU8A0SMyGDtEOY/l/s/1Uw= +github.com/aws/aws-sdk-go-v2/service/sso v1.30.8/go.mod h1:+fWt2UHSb4kS7Pu8y+BMBvJF0EWx+4H0hzNwtDNRTrg= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.12 h1:AHDr0DaHIAo8c9t1emrzAlVDFp+iMMKnPdYy6XO4MCE= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.12/go.mod h1:GQ73XawFFiWxyWXMHWfhiomvP3tXtdNar/fi8z18sx0= +github.com/aws/aws-sdk-go-v2/service/sts v1.41.5 h1:SciGFVNZ4mHdm7gpD1dgZYnCuVdX1s+lFTg4+4DOy70= +github.com/aws/aws-sdk-go-v2/service/sts v1.41.5/go.mod h1:iW40X4QBmUxdP+fZNOpfmkdMZqsovezbAeO+Ubiv2pk= +github.com/aws/smithy-go v1.24.0 h1:LpilSUItNPFr1eY85RYgTIg5eIEPtvFbskaFcmmIUnk= +github.com/aws/smithy-go v1.24.0/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0= github.com/bmatcuk/doublestar v1.3.4 h1:gPypJ5xD31uhX6Tf54sDPUOBXTqKH4c9aPY66CyQrS0= github.com/bmatcuk/doublestar v1.3.4/go.mod h1:wiQtGV+rzVYxB7WIlirSN++5HPtPlXEo9MEoZQC/PmE= +github.com/bmatcuk/doublestar/v4 v4.6.1 h1:FH9SifrbvJhnlQpztAx++wlkk70QBf0iBWDwNy7PA4I= +github.com/bmatcuk/doublestar/v4 v4.6.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= +github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= +github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c= +github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= +github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= +github.com/casbin/casbin/v2 v2.103.0 h1:dHElatNXNrr8XcseUov0ZSiWjauwmZZE6YMV3eU1yic= +github.com/casbin/casbin/v2 v2.103.0/go.mod h1:Ee33aqGrmES+GNL17L0h9X28wXuo829wnNUnS0edAco= +github.com/casbin/gorm-adapter/v3 v3.32.0 h1:Au+IOILBIE9clox5BJhI2nA3p9t7Ep1ePlupdGbGfus= +github.com/casbin/gorm-adapter/v3 v3.32.0/go.mod h1:Zre/H8p17mpv5U3EaWgPoxLILLdXO3gHW5aoQQpUDZI= +github.com/casbin/govaluate v1.3.0 h1:VA0eSY0M2lA86dYd5kPPuNZMUD9QkWnOCnavGrw9myc= +github.com/casbin/govaluate v1.3.0/go.mod h1:G/UnbIjZk/0uMNaLwZZmFQrR72tYRZWQkO70si/iR7A= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/clbanning/mxj v1.8.4 h1:HuhwZtbyvyOw+3Z1AowPkU87JkJUSv751ELWaiTpj8I= +github.com/clbanning/mxj v1.8.4/go.mod h1:BVjHeAH+rl9rs6f+QIpeRl0tfu10SXn1pUSa5PVGJng= github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443 h1:aQ3y1lwWyqYPiWZThqv1aFbZMiM9vblcSArJRf2Irls= github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/dave/jennifer v1.6.1/go.mod h1:nXbxhEmQfOZhWml3D1cDK5M1FLnMSozpbFN/m3RmGZc= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= +github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko= +github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= +github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/envoyproxy/go-control-plane v0.13.4 h1:zEqyPVyku6IvWCFwux4x9RxkLOMUL+1vC9xUFv5l2/M= github.com/envoyproxy/go-control-plane/envoy v1.32.4 h1:jb83lalDRZSpPWW2Z7Mck/8kXZ5CQAFYVjQcdVIr83A= github.com/envoyproxy/go-control-plane/envoy v1.32.4/go.mod h1:Gzjc5k8JcJswLjAx1Zm+wSYE20UrLtt7JZMWiWQXQEw= @@ -27,6 +115,14 @@ github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfU github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/gammazero/toposort v0.1.1 h1:OivGxsWxF3U3+U80VoLJ+f50HcPU1MIqE1JlKzoJ2Eg= +github.com/gammazero/toposort v0.1.1/go.mod h1:H2cozTnNpMw0hg2VHAYsAxmkHXBYroNangj2NTBQDvw= +github.com/glebarez/go-sqlite v1.21.2 h1:3a6LFC4sKahUunAmynQKLZceZCOzUthkRkEAl9gAXWo= +github.com/glebarez/go-sqlite v1.21.2/go.mod h1:sfxdZyhQjTM2Wry3gVYWaW072Ri1WMdWJi0k6+3382k= +github.com/glebarez/sqlite v1.11.0 h1:wSG0irqzP6VurnMEpFGer5Li19RpIRi2qvQz++w0GMw= +github.com/glebarez/sqlite v1.11.0/go.mod h1:h8/o8j5wiAsqSPoWELDUdJXhjAhsVliSn7bWZjOhrgQ= +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-kratos/aegis v0.2.0 h1:dObzCDWn3XVjUkgxyBp6ZeWtx/do0DPZ7LY3yNSJLUQ= github.com/go-kratos/aegis v0.2.0/go.mod h1:v0R2m73WgEEYB3XYu6aE2WcMwsZkJ/Rzuf5eVccm7bI= github.com/go-kratos/aip-go/ents v0.0.0-20251213081434-74ffa1fc1588 h1:e0dWyNWFeTgGCH7cRMROahTwMaQYtmHce/6fxVmA6yI= @@ -42,57 +138,190 @@ github.com/go-openapi/inflect v0.19.0 h1:9jCH9scKIbHeV9m12SmPilScz6krDxKRasNNSNP github.com/go-openapi/inflect v0.19.0/go.mod h1:lHpZVlpIQqLyKwJ4N+YSc9hchQy/i12fJykb83CRBH4= github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= -github.com/go-playground/form/v4 v4.2.1 h1:HjdRDKO0fftVMU5epjPW2SOREcZ6/wLUzEobqUGJuPw= -github.com/go-playground/form/v4 v4.2.1/go.mod h1:q1a2BY+AQUUzhl6xA/6hBetay6dEIhMHjgvJiGo6K7U= -github.com/go-sql-driver/mysql v1.9.3 h1:U/N249h2WzJ3Ukj8SowVFjdtZKfu9vlLZxjPXV1aweo= -github.com/go-sql-driver/mysql v1.9.3/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU= +github.com/go-playground/form/v4 v4.2.0 h1:N1wh+Goz61e6w66vo8vJkQt+uwZSoLz50kZPJWR8eic= +github.com/go-playground/form/v4 v4.2.0/go.mod h1:q1a2BY+AQUUzhl6xA/6hBetay6dEIhMHjgvJiGo6K7U= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= +github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= +github.com/go-playground/validator/v10 v10.7.0/go.mod h1:xm76BBt941f7yWdGnI2DVPFFg1UK3YY04qifoXU3lOk= +github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= +github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= +github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= -github.com/golang-jwt/jwt/v5 v5.1.0 h1:UGKbA/IPjtS6zLcdB7i5TyACMgSbOTiR8qzXgw8HWQU= -github.com/golang-jwt/jwt/v5 v5.1.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +github.com/goccy/go-json v0.10.4 h1:JSwxQzIqKfmFX1swYPpUThQZp/Ka4wzJdK0LWVytLPM= +github.com/goccy/go-json v0.10.4/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= +github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= +github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= +github.com/golang-jwt/jwt/v4 v4.4.3/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8= +github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA= +github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= +github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A= +github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= +github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= +github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ= +github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo= github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0/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/google/wire v0.6.0 h1:HBkoIh4BdSxoyo9PveV8giw7ZsaBOvzWKfcg/6MrVwI= github.com/google/wire v0.6.0/go.mod h1:F4QhpQ9EDIdJ1Mbop/NZBRB+5yrR6qg3BnctaoUk6NA= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= +github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= +github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= +github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/hcl/v2 v2.18.1 h1:6nxnOJFku1EuSawSD81fuviYUV8DxFr3fp2dUi3ZYSo= github.com/hashicorp/hcl/v2 v2.18.1/go.mod h1:ThLC89FV4p9MPW804KVbe/cEXoQ8NZEh+JtMeeGErHE= +github.com/huaweicloud/huaweicloud-sdk-go-obs v3.24.9+incompatible h1:XQVXdk+WAJ4fSNB6mMRuYNvFWou7BZs6SZB925hPrnk= +github.com/huaweicloud/huaweicloud-sdk-go-obs v3.24.9+incompatible/go.mod h1:l7VUhRbTKCzdOacdT4oWCwATKyvZqUOlOqr0Ous3k4s= +github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= +github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= +github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= +github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk= +github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= +github.com/jackc/pgx/v5 v5.5.5 h1:amBjrZVmksIdNjxGW/IiIMzxMKZFelXbUoPNb+8sjQw= +github.com/jackc/pgx/v5 v5.5.5/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A= +github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk= +github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= +github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs= +github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM= +github.com/jcmturner/gofork v1.7.6/go.mod h1:1622LH6i/EZqLloHfE7IeZ0uEJwMSUyQ/nDd82IeqRo= +github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg= +github.com/jcmturner/gokrb5/v8 v8.4.4/go.mod h1:1btQEpgT6k+unzCwX1KdWMEwPPkkgBtP+F6aCACiMrs= +github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= +github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= +github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= +github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= +github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.2.9 h1:66ze0taIn2H33fBvCkXuv9BmCwDfafmiIVpKV9kKGuY= +github.com/klauspost/cpuid/v2 v2.2.9/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK4QwQ3WMXF8= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6YIM= -github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= +github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8= +github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= +github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= +github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/microsoft/go-mssqldb v1.6.0 h1:mM3gYdVwEPFrlg/Dvr2DNVEgYFG7L42l+dGc67NNNpc= +github.com/microsoft/go-mssqldb v1.6.0/go.mod h1:00mDtPbeQCRGC1HwOOR5K/gr30P1NcEG0vx6Kbv2aJU= +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.84 h1:D1HVmAF8JF8Bpi6IU4V9vIEj+8pc+xU88EWMs2yed0E= +github.com/minio/minio-go/v7 v7.0.84/go.mod h1:57YXpvc5l3rjPdhqNrDsvVlY0qPI6UTk1bflAe+9doY= github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= +github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= +github.com/mojocn/base64Captcha v1.3.8 h1:rrN9BhCwXKS8ht1e21kvR3iTaMgf4qPC9sRoV52bqEg= +github.com/mojocn/base64Captcha v1.3.8/go.mod h1:QFZy927L8HVP3+VV5z2b1EAEiv1KxVJKZbAucVgLUy4= +github.com/montanaflynn/stats v0.7.0/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= +github.com/mozillazg/go-httpheader v0.2.1 h1:geV7TrjbL8KXSyvghnFm+NyTux/hxwueTSrwhe88TQQ= +github.com/mozillazg/go-httpheader v0.2.1/go.mod h1:jJ8xECTlalr6ValeXYdOF8fFUISeBAdw6E61aqQma60= +github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU= +github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo= github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g= github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= +github.com/qiniu/dyn v1.3.0/go.mod h1:E8oERcm8TtwJiZvkQPbcAh0RL8jO1G0VXJMW3FAWdkk= +github.com/qiniu/go-sdk/v7 v7.25.2 h1:URwgZpxySdiwu2yQpHk93X4LXWHyFRp1x3Vmlk/YWvo= +github.com/qiniu/go-sdk/v7 v7.25.2/go.mod h1:dmKtJ2ahhPWFVi9o1D5GemmWoh/ctuB9peqTowyTO8o= +github.com/qiniu/x v1.10.5/go.mod h1:03Ni9tj+N2h2aKnAz+6N0Xfl8FwMEDRC2PAlxekASDs= +github.com/redis/go-redis/v9 v9.7.0 h1:HhLSs+B6O021gwzl+locl0zEDnyNkxMtf/Z3NNBMa9E= +github.com/redis/go-redis/v9 v9.7.0/go.mod h1:f6zhXITC7JUJIlPEiBOTXxJgPLdZcA93GewI7inzyWw= +github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= +github.com/richardlehane/mscfb v1.0.4 h1:WULscsljNPConisD5hR0+OyZjwK46Pfyr6mPu5ZawpM= +github.com/richardlehane/mscfb v1.0.4/go.mod h1:YzVpcZg9czvAuhk9T+a3avCpcFPMUWm7gK3DypaEsUk= +github.com/richardlehane/msoleps v1.0.1/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg= +github.com/richardlehane/msoleps v1.0.4 h1:WuESlvhX3gH2IHcd8UqyCuFY5yiq/GR/yqaSM/9/g00= +github.com/richardlehane/msoleps v1.0.4/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg= +github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= +github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= 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/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU= +github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= +github.com/stretchr/objx v0.1.0/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/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.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.563/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/kms v1.0.563/go.mod h1:uom4Nvi9W+Qkom0exYiJ9VWJjXwyxtPYTkKkaLMlfE0= +github.com/tencentyun/cos-go-sdk-v5 v0.7.60 h1:/e/tmvRmfKexr/QQIBzWhOkZWsmY3EK72NrI6G/Tv0o= +github.com/tencentyun/cos-go-sdk-v5 v0.7.60/go.mod h1:8+hG+mQMuRP/OIS9d83syAvXvrMj9HhkND6Q1fLghw0= +github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d h1:llb0neMWDQe87IzJLS4Ci7psK/lVsjIS2otl+1WyRyY= +github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI= +github.com/xuri/excelize/v2 v2.9.0 h1:1tgOaEq92IOEumR1/JfYS/eR0KHOCsRv/rYXXh6YJQE= +github.com/xuri/excelize/v2 v2.9.0/go.mod h1:uqey4QBZ9gdMeWApPLdhm9x+9o2lq4iVmjiLfBS5hdE= +github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7 h1:hPVCafDV85blFTabnqKgNhDCkJX25eik94Si9cTER4A= +github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zclconf/go-cty v1.14.4 h1:uXXczd9QDGsgu0i/QFR/hzI5NYCHLf6NQw/atrbnhq8= github.com/zclconf/go-cty v1.14.4/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= github.com/zclconf/go-cty-yaml v1.1.0 h1:nP+jp0qPHv2IhUVqmQSzjvqAWcObN0KBkUl2rWBdig0= github.com/zclconf/go-cty-yaml v1.1.0/go.mod h1:9YLUH4g7lOhVWqUbctnVlZ5KLpg7JAprQNgxSZ1Gyxs= -go.einride.tech/aip v0.76.0 h1:JGz5u/67eBGfM02ubGNZtsGSU0vY2zMTWRbadgEkQoM= -go.einride.tech/aip v0.76.0/go.mod h1:E8+wdTApA70odnpFzJgsGogHozC2JCIhFJBKPr8bVig= +go.einride.tech/aip v0.78.0 h1:nbnM/OuGt5Pyz/r2KOxB6Hp+ey2e0+MNnfIPBtY45pY= +go.einride.tech/aip v0.78.0/go.mod h1:E8+wdTApA70odnpFzJgsGogHozC2JCIhFJBKPr8bVig= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= go.opentelemetry.io/otel v1.36.0 h1:UumtzIklRBY6cI/lllNZlALOF5nNIzJVb16APdvgTXg= @@ -105,25 +334,47 @@ go.opentelemetry.io/otel/sdk/metric v1.36.0 h1:r0ntwwGosWGaa0CrSt8cuNuTcccMXERFw go.opentelemetry.io/otel/sdk/metric v1.36.0/go.mod h1:qTNOhFDfKRwX0yXOqJYegL5WRaW376QbB7P4Pb0qva4= go.opentelemetry.io/otel/trace v1.36.0 h1:ahxWNuqZjpdiFAyrIoQ4GIiAIhxAunQR6MUoKrsNd4w= go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA= -go.uber.org/automaxprocs v1.5.1 h1:e1YG66Lrk73dn4qhg8WFSvhF0JuFQF0ERIp4rpuV8Qk= -go.uber.org/automaxprocs v1.5.1/go.mod h1:BF4eumQw0P9GtnuxxovUd06vwm1o18oMzFtK66vU6XU= +go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs= +go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +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.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= +golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= +golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= +golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8= +golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw= +golang.org/x/image v0.23.0 h1:HseQ7c2OpPKTPVzNjG5fwJsOTCiiwS4QdsYi5XU6H68= +golang.org/x/image v0.23.0/go.mod h1:wJJBTdLfCCf3tiHa1fNxpZmUI4mmoZvwMCPP0ddoNKY= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM= golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= +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-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/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-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY= golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -131,41 +382,66 @@ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ= golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/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-20210616045830-e2b7044e8c71/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-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= 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/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= 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.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4= golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA= +golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= +golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d h1:/hmn0Ku5kWij/kjGsrcJeC1T/MrJi2iNWwgAqrihFwc= google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d/go.mod h1:FfBgJBJg9GcpPvKIuHSZ/aE1g2ecGL74upMzGZjiGEY= @@ -178,9 +454,44 @@ google.golang.org/grpc v1.74.2/go.mod h1:CtQ+BGjaAIXHs/5YS3i473GqwBBa1zGQNevxdeB 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/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/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/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +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.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gorm.io/driver/mysql v1.5.7 h1:MndhOPYOfEp2rHKgkZIhJ16eVUIRf2HmzgoPmh7FCWo= +gorm.io/driver/mysql v1.5.7/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM= +gorm.io/driver/postgres v1.5.11 h1:ubBVAfbKEUld/twyKZ0IYn9rSQh448EdelLYk9Mv314= +gorm.io/driver/postgres v1.5.11/go.mod h1:DX3GReXH+3FPWGrrgffdvCk3DQ1dwDPdmbenSkweRGI= +gorm.io/driver/sqlite v1.6.0 h1:WHRRrIiulaPiPFmDcod6prc4l2VGVWHz80KspNsxSfQ= +gorm.io/driver/sqlite v1.6.0/go.mod h1:AO9V1qIQddBESngQUKWL9yoH93HIeA1X6V633rBwyT8= +gorm.io/driver/sqlserver v1.5.3 h1:rjupPS4PVw+rjJkfvr8jn2lJ8BMhT4UW5FwuJY0P3Z0= +gorm.io/driver/sqlserver v1.5.3/go.mod h1:B+CZ0/7oFJ6tAlefsKoyxdgDCXJKSgwS2bMOQZT0I00= +gorm.io/gorm v1.25.7-0.20240204074919-46816ad31dde/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= +gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= +gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ= +gorm.io/gorm v1.30.0 h1:qbT5aPv1UH8gI99OsRlvDToLxW5zR7FzS9acZDOZcgs= +gorm.io/gorm v1.30.0/go.mod h1:8Z33v652h4//uMA76KjeDH8mJXPm1QNCYrMeatR0DOE= +gorm.io/plugin/dbresolver v1.5.3 h1:wFwINGZZmttuu9h7XpvbDHd8Lf9bb8GNzp/NpAMV2wU= +gorm.io/plugin/dbresolver v1.5.3/go.mod h1:TSrVhaUg2DZAWP3PrHlDlITEJmNOkL0tFTjvTEsQ4XE= +gorm.io/plugin/dbresolver v1.6.2 h1:F4b85TenghUeITqe3+epPSUtHH7RIk3fXr5l83DF8Pc= +gorm.io/plugin/dbresolver v1.6.2/go.mod h1:tctw63jdrOezFR9HmrKnPkmig3m5Edem9fdxk9bQSzM= gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q= gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA= +modernc.org/fileutil v1.0.0 h1:Z1AFLZwl6BO8A5NldQg/xTSjGLetp+1Ubvl4alfGx8w= +modernc.org/fileutil v1.0.0/go.mod h1:JHsWpkrk/CnVV1H/eGlFf85BEpfkrp56ro8nojIq9Q8= +modernc.org/libc v1.22.5 h1:91BNch/e5B0uPbJFgqbxXuOnxBQjlS//icfQEGmvyjE= +modernc.org/libc v1.22.5/go.mod h1:jj+Z7dTNX8fBScMVNRAYZ/jF91K8fdT2hYMThc3YjBY= +modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ= +modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= +modernc.org/memory v1.5.0 h1:N+/8c5rE6EqugZwHii4IFsaJ7MUhoWX07J5tC/iI5Ds= +modernc.org/memory v1.5.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= +modernc.org/sqlite v1.23.1 h1:nrSBg4aRQQwq59JpvGEQ15tNxoO5pX/kUjcRNwSAGQM= +modernc.org/sqlite v1.23.1/go.mod h1:OrDj17Mggn6MhE+iPbBNf7RGKODDE9NFT0f3EwDzJqk= diff --git a/internal/conf/conf.pb.go b/internal/conf/conf.pb.go index 0ae7ff7..955e93e 100644 --- a/internal/conf/conf.pb.go +++ b/internal/conf/conf.pb.go @@ -1,8 +1,8 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.36.5 -// protoc v4.23.2 -// source: conf/conf.proto +// protoc-gen-go v1.36.11 +// protoc v5.28.3 +// source: conf.proto package conf @@ -26,13 +26,17 @@ type Bootstrap struct { state protoimpl.MessageState `protogen:"open.v1"` Server *Server `protobuf:"bytes,1,opt,name=server,proto3" json:"server,omitempty"` Data *Data `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` + Jwt *JWT `protobuf:"bytes,3,opt,name=jwt,proto3" json:"jwt,omitempty"` + Casbin *Casbin `protobuf:"bytes,4,opt,name=casbin,proto3" json:"casbin,omitempty"` + Captcha *Captcha `protobuf:"bytes,5,opt,name=captcha,proto3" json:"captcha,omitempty"` + Upload *Upload `protobuf:"bytes,6,opt,name=upload,proto3" json:"upload,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } func (x *Bootstrap) Reset() { *x = Bootstrap{} - mi := &file_conf_conf_proto_msgTypes[0] + mi := &file_conf_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -44,7 +48,7 @@ func (x *Bootstrap) String() string { func (*Bootstrap) ProtoMessage() {} func (x *Bootstrap) ProtoReflect() protoreflect.Message { - mi := &file_conf_conf_proto_msgTypes[0] + mi := &file_conf_proto_msgTypes[0] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -57,7 +61,7 @@ func (x *Bootstrap) ProtoReflect() protoreflect.Message { // Deprecated: Use Bootstrap.ProtoReflect.Descriptor instead. func (*Bootstrap) Descriptor() ([]byte, []int) { - return file_conf_conf_proto_rawDescGZIP(), []int{0} + return file_conf_proto_rawDescGZIP(), []int{0} } func (x *Bootstrap) GetServer() *Server { @@ -74,6 +78,34 @@ func (x *Bootstrap) GetData() *Data { return nil } +func (x *Bootstrap) GetJwt() *JWT { + if x != nil { + return x.Jwt + } + return nil +} + +func (x *Bootstrap) GetCasbin() *Casbin { + if x != nil { + return x.Casbin + } + return nil +} + +func (x *Bootstrap) GetCaptcha() *Captcha { + if x != nil { + return x.Captcha + } + return nil +} + +func (x *Bootstrap) GetUpload() *Upload { + if x != nil { + return x.Upload + } + return nil +} + type Server struct { state protoimpl.MessageState `protogen:"open.v1"` Http *Server_HTTP `protobuf:"bytes,1,opt,name=http,proto3" json:"http,omitempty"` @@ -84,7 +116,7 @@ type Server struct { func (x *Server) Reset() { *x = Server{} - mi := &file_conf_conf_proto_msgTypes[1] + mi := &file_conf_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -96,7 +128,7 @@ func (x *Server) String() string { func (*Server) ProtoMessage() {} func (x *Server) ProtoReflect() protoreflect.Message { - mi := &file_conf_conf_proto_msgTypes[1] + mi := &file_conf_proto_msgTypes[1] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -109,7 +141,7 @@ func (x *Server) ProtoReflect() protoreflect.Message { // Deprecated: Use Server.ProtoReflect.Descriptor instead. func (*Server) Descriptor() ([]byte, []int) { - return file_conf_conf_proto_rawDescGZIP(), []int{1} + return file_conf_proto_rawDescGZIP(), []int{1} } func (x *Server) GetHttp() *Server_HTTP { @@ -136,7 +168,7 @@ type Data struct { func (x *Data) Reset() { *x = Data{} - mi := &file_conf_conf_proto_msgTypes[2] + mi := &file_conf_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -148,7 +180,7 @@ func (x *Data) String() string { func (*Data) ProtoMessage() {} func (x *Data) ProtoReflect() protoreflect.Message { - mi := &file_conf_conf_proto_msgTypes[2] + mi := &file_conf_proto_msgTypes[2] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -161,7 +193,7 @@ func (x *Data) ProtoReflect() protoreflect.Message { // Deprecated: Use Data.ProtoReflect.Descriptor instead. func (*Data) Descriptor() ([]byte, []int) { - return file_conf_conf_proto_rawDescGZIP(), []int{2} + return file_conf_proto_rawDescGZIP(), []int{2} } func (x *Data) GetDatabase() *Data_Database { @@ -178,6 +210,318 @@ func (x *Data) GetRedis() *Data_Redis { return nil } +type JWT struct { + state protoimpl.MessageState `protogen:"open.v1"` + SigningKey string `protobuf:"bytes,1,opt,name=signing_key,json=signingKey,proto3" json:"signing_key,omitempty"` + ExpiresTime string `protobuf:"bytes,2,opt,name=expires_time,json=expiresTime,proto3" json:"expires_time,omitempty"` + BufferTime string `protobuf:"bytes,3,opt,name=buffer_time,json=bufferTime,proto3" json:"buffer_time,omitempty"` + Issuer string `protobuf:"bytes,4,opt,name=issuer,proto3" json:"issuer,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *JWT) Reset() { + *x = JWT{} + mi := &file_conf_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *JWT) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*JWT) ProtoMessage() {} + +func (x *JWT) ProtoReflect() protoreflect.Message { + mi := &file_conf_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use JWT.ProtoReflect.Descriptor instead. +func (*JWT) Descriptor() ([]byte, []int) { + return file_conf_proto_rawDescGZIP(), []int{3} +} + +func (x *JWT) GetSigningKey() string { + if x != nil { + return x.SigningKey + } + return "" +} + +func (x *JWT) GetExpiresTime() string { + if x != nil { + return x.ExpiresTime + } + return "" +} + +func (x *JWT) GetBufferTime() string { + if x != nil { + return x.BufferTime + } + return "" +} + +func (x *JWT) GetIssuer() string { + if x != nil { + return x.Issuer + } + return "" +} + +type Casbin struct { + state protoimpl.MessageState `protogen:"open.v1"` + ModelPath string `protobuf:"bytes,1,opt,name=model_path,json=modelPath,proto3" json:"model_path,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Casbin) Reset() { + *x = Casbin{} + mi := &file_conf_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Casbin) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Casbin) ProtoMessage() {} + +func (x *Casbin) ProtoReflect() protoreflect.Message { + mi := &file_conf_proto_msgTypes[4] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Casbin.ProtoReflect.Descriptor instead. +func (*Casbin) Descriptor() ([]byte, []int) { + return file_conf_proto_rawDescGZIP(), []int{4} +} + +func (x *Casbin) GetModelPath() string { + if x != nil { + return x.ModelPath + } + return "" +} + +type Captcha struct { + state protoimpl.MessageState `protogen:"open.v1"` + KeyLong int32 `protobuf:"varint,1,opt,name=key_long,json=keyLong,proto3" json:"key_long,omitempty"` + ImgWidth int32 `protobuf:"varint,2,opt,name=img_width,json=imgWidth,proto3" json:"img_width,omitempty"` + ImgHeight int32 `protobuf:"varint,3,opt,name=img_height,json=imgHeight,proto3" json:"img_height,omitempty"` + OpenCaptcha int32 `protobuf:"varint,4,opt,name=open_captcha,json=openCaptcha,proto3" json:"open_captcha,omitempty"` + OpenCaptchaTimeout int32 `protobuf:"varint,5,opt,name=open_captcha_timeout,json=openCaptchaTimeout,proto3" json:"open_captcha_timeout,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Captcha) Reset() { + *x = Captcha{} + mi := &file_conf_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Captcha) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Captcha) ProtoMessage() {} + +func (x *Captcha) ProtoReflect() protoreflect.Message { + mi := &file_conf_proto_msgTypes[5] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Captcha.ProtoReflect.Descriptor instead. +func (*Captcha) Descriptor() ([]byte, []int) { + return file_conf_proto_rawDescGZIP(), []int{5} +} + +func (x *Captcha) GetKeyLong() int32 { + if x != nil { + return x.KeyLong + } + return 0 +} + +func (x *Captcha) GetImgWidth() int32 { + if x != nil { + return x.ImgWidth + } + return 0 +} + +func (x *Captcha) GetImgHeight() int32 { + if x != nil { + return x.ImgHeight + } + return 0 +} + +func (x *Captcha) GetOpenCaptcha() int32 { + if x != nil { + return x.OpenCaptcha + } + return 0 +} + +func (x *Captcha) GetOpenCaptchaTimeout() int32 { + if x != nil { + return x.OpenCaptchaTimeout + } + return 0 +} + +type Upload struct { + state protoimpl.MessageState `protogen:"open.v1"` + Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` + Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"` + MaxSize int64 `protobuf:"varint,3,opt,name=max_size,json=maxSize,proto3" json:"max_size,omitempty"` + Local *Upload_Local `protobuf:"bytes,4,opt,name=local,proto3" json:"local,omitempty"` + Aliyun *Upload_Aliyun `protobuf:"bytes,5,opt,name=aliyun,proto3" json:"aliyun,omitempty"` + Tencent *Upload_Tencent `protobuf:"bytes,6,opt,name=tencent,proto3" json:"tencent,omitempty"` + Qiniu *Upload_Qiniu `protobuf:"bytes,7,opt,name=qiniu,proto3" json:"qiniu,omitempty"` + Minio *Upload_Minio `protobuf:"bytes,8,opt,name=minio,proto3" json:"minio,omitempty"` + AwsS3 *Upload_AwsS3 `protobuf:"bytes,9,opt,name=aws_s3,json=awsS3,proto3" json:"aws_s3,omitempty"` + HuaweiObs *Upload_HuaweiObs `protobuf:"bytes,10,opt,name=huawei_obs,json=huaweiObs,proto3" json:"huawei_obs,omitempty"` + CloudflareR2 *Upload_CloudflareR2 `protobuf:"bytes,11,opt,name=cloudflare_r2,json=cloudflareR2,proto3" json:"cloudflare_r2,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Upload) Reset() { + *x = Upload{} + mi := &file_conf_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Upload) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Upload) ProtoMessage() {} + +func (x *Upload) ProtoReflect() protoreflect.Message { + mi := &file_conf_proto_msgTypes[6] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Upload.ProtoReflect.Descriptor instead. +func (*Upload) Descriptor() ([]byte, []int) { + return file_conf_proto_rawDescGZIP(), []int{6} +} + +func (x *Upload) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *Upload) GetPath() string { + if x != nil { + return x.Path + } + return "" +} + +func (x *Upload) GetMaxSize() int64 { + if x != nil { + return x.MaxSize + } + return 0 +} + +func (x *Upload) GetLocal() *Upload_Local { + if x != nil { + return x.Local + } + return nil +} + +func (x *Upload) GetAliyun() *Upload_Aliyun { + if x != nil { + return x.Aliyun + } + return nil +} + +func (x *Upload) GetTencent() *Upload_Tencent { + if x != nil { + return x.Tencent + } + return nil +} + +func (x *Upload) GetQiniu() *Upload_Qiniu { + if x != nil { + return x.Qiniu + } + return nil +} + +func (x *Upload) GetMinio() *Upload_Minio { + if x != nil { + return x.Minio + } + return nil +} + +func (x *Upload) GetAwsS3() *Upload_AwsS3 { + if x != nil { + return x.AwsS3 + } + return nil +} + +func (x *Upload) GetHuaweiObs() *Upload_HuaweiObs { + if x != nil { + return x.HuaweiObs + } + return nil +} + +func (x *Upload) GetCloudflareR2() *Upload_CloudflareR2 { + if x != nil { + return x.CloudflareR2 + } + return nil +} + type Server_HTTP struct { state protoimpl.MessageState `protogen:"open.v1"` Network string `protobuf:"bytes,1,opt,name=network,proto3" json:"network,omitempty"` @@ -189,7 +533,7 @@ type Server_HTTP struct { func (x *Server_HTTP) Reset() { *x = Server_HTTP{} - mi := &file_conf_conf_proto_msgTypes[3] + mi := &file_conf_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -201,7 +545,7 @@ func (x *Server_HTTP) String() string { func (*Server_HTTP) ProtoMessage() {} func (x *Server_HTTP) ProtoReflect() protoreflect.Message { - mi := &file_conf_conf_proto_msgTypes[3] + mi := &file_conf_proto_msgTypes[7] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -214,7 +558,7 @@ func (x *Server_HTTP) ProtoReflect() protoreflect.Message { // Deprecated: Use Server_HTTP.ProtoReflect.Descriptor instead. func (*Server_HTTP) Descriptor() ([]byte, []int) { - return file_conf_conf_proto_rawDescGZIP(), []int{1, 0} + return file_conf_proto_rawDescGZIP(), []int{1, 0} } func (x *Server_HTTP) GetNetwork() string { @@ -249,7 +593,7 @@ type Server_GRPC struct { func (x *Server_GRPC) Reset() { *x = Server_GRPC{} - mi := &file_conf_conf_proto_msgTypes[4] + mi := &file_conf_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -261,7 +605,7 @@ func (x *Server_GRPC) String() string { func (*Server_GRPC) ProtoMessage() {} func (x *Server_GRPC) ProtoReflect() protoreflect.Message { - mi := &file_conf_conf_proto_msgTypes[4] + mi := &file_conf_proto_msgTypes[8] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -274,7 +618,7 @@ func (x *Server_GRPC) ProtoReflect() protoreflect.Message { // Deprecated: Use Server_GRPC.ProtoReflect.Descriptor instead. func (*Server_GRPC) Descriptor() ([]byte, []int) { - return file_conf_conf_proto_rawDescGZIP(), []int{1, 1} + return file_conf_proto_rawDescGZIP(), []int{1, 1} } func (x *Server_GRPC) GetNetwork() string { @@ -302,13 +646,18 @@ type Data_Database struct { state protoimpl.MessageState `protogen:"open.v1"` Driver string `protobuf:"bytes,1,opt,name=driver,proto3" json:"driver,omitempty"` Source string `protobuf:"bytes,2,opt,name=source,proto3" json:"source,omitempty"` + TablePrefix string `protobuf:"bytes,3,opt,name=table_prefix,json=tablePrefix,proto3" json:"table_prefix,omitempty"` + MaxIdleConns int32 `protobuf:"varint,4,opt,name=max_idle_conns,json=maxIdleConns,proto3" json:"max_idle_conns,omitempty"` + MaxOpenConns int32 `protobuf:"varint,5,opt,name=max_open_conns,json=maxOpenConns,proto3" json:"max_open_conns,omitempty"` + MaxLifetime int32 `protobuf:"varint,6,opt,name=max_lifetime,json=maxLifetime,proto3" json:"max_lifetime,omitempty"` + LogMode bool `protobuf:"varint,7,opt,name=log_mode,json=logMode,proto3" json:"log_mode,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } func (x *Data_Database) Reset() { *x = Data_Database{} - mi := &file_conf_conf_proto_msgTypes[5] + mi := &file_conf_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -320,7 +669,7 @@ func (x *Data_Database) String() string { func (*Data_Database) ProtoMessage() {} func (x *Data_Database) ProtoReflect() protoreflect.Message { - mi := &file_conf_conf_proto_msgTypes[5] + mi := &file_conf_proto_msgTypes[9] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -333,7 +682,7 @@ func (x *Data_Database) ProtoReflect() protoreflect.Message { // Deprecated: Use Data_Database.ProtoReflect.Descriptor instead. func (*Data_Database) Descriptor() ([]byte, []int) { - return file_conf_conf_proto_rawDescGZIP(), []int{2, 0} + return file_conf_proto_rawDescGZIP(), []int{2, 0} } func (x *Data_Database) GetDriver() string { @@ -350,19 +699,55 @@ func (x *Data_Database) GetSource() string { return "" } +func (x *Data_Database) GetTablePrefix() string { + if x != nil { + return x.TablePrefix + } + return "" +} + +func (x *Data_Database) GetMaxIdleConns() int32 { + if x != nil { + return x.MaxIdleConns + } + return 0 +} + +func (x *Data_Database) GetMaxOpenConns() int32 { + if x != nil { + return x.MaxOpenConns + } + return 0 +} + +func (x *Data_Database) GetMaxLifetime() int32 { + if x != nil { + return x.MaxLifetime + } + return 0 +} + +func (x *Data_Database) GetLogMode() bool { + if x != nil { + return x.LogMode + } + return false +} + type Data_Redis struct { state protoimpl.MessageState `protogen:"open.v1"` - Network string `protobuf:"bytes,1,opt,name=network,proto3" json:"network,omitempty"` - Addr string `protobuf:"bytes,2,opt,name=addr,proto3" json:"addr,omitempty"` - ReadTimeout *durationpb.Duration `protobuf:"bytes,3,opt,name=read_timeout,json=readTimeout,proto3" json:"read_timeout,omitempty"` - WriteTimeout *durationpb.Duration `protobuf:"bytes,4,opt,name=write_timeout,json=writeTimeout,proto3" json:"write_timeout,omitempty"` + Addr string `protobuf:"bytes,1,opt,name=addr,proto3" json:"addr,omitempty"` + Password string `protobuf:"bytes,2,opt,name=password,proto3" json:"password,omitempty"` + Db int32 `protobuf:"varint,3,opt,name=db,proto3" json:"db,omitempty"` + UseCluster bool `protobuf:"varint,4,opt,name=use_cluster,json=useCluster,proto3" json:"use_cluster,omitempty"` + ClusterAddrs []string `protobuf:"bytes,5,rep,name=cluster_addrs,json=clusterAddrs,proto3" json:"cluster_addrs,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } func (x *Data_Redis) Reset() { *x = Data_Redis{} - mi := &file_conf_conf_proto_msgTypes[6] + mi := &file_conf_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -374,7 +759,7 @@ func (x *Data_Redis) String() string { func (*Data_Redis) ProtoMessage() {} func (x *Data_Redis) ProtoReflect() protoreflect.Message { - mi := &file_conf_conf_proto_msgTypes[6] + mi := &file_conf_proto_msgTypes[10] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -387,14 +772,7 @@ func (x *Data_Redis) ProtoReflect() protoreflect.Message { // Deprecated: Use Data_Redis.ProtoReflect.Descriptor instead. func (*Data_Redis) Descriptor() ([]byte, []int) { - return file_conf_conf_proto_rawDescGZIP(), []int{2, 1} -} - -func (x *Data_Redis) GetNetwork() string { - if x != nil { - return x.Network - } - return "" + return file_conf_proto_rawDescGZIP(), []int{2, 1} } func (x *Data_Redis) GetAddr() string { @@ -404,141 +782,915 @@ func (x *Data_Redis) GetAddr() string { return "" } -func (x *Data_Redis) GetReadTimeout() *durationpb.Duration { +func (x *Data_Redis) GetPassword() string { if x != nil { - return x.ReadTimeout + return x.Password + } + return "" +} + +func (x *Data_Redis) GetDb() int32 { + if x != nil { + return x.Db + } + return 0 +} + +func (x *Data_Redis) GetUseCluster() bool { + if x != nil { + return x.UseCluster + } + return false +} + +func (x *Data_Redis) GetClusterAddrs() []string { + if x != nil { + return x.ClusterAddrs } return nil } -func (x *Data_Redis) GetWriteTimeout() *durationpb.Duration { - if x != nil { - return x.WriteTimeout - } - return nil +type Upload_Local struct { + state protoimpl.MessageState `protogen:"open.v1"` + StorePath string `protobuf:"bytes,1,opt,name=store_path,json=storePath,proto3" json:"store_path,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } -var File_conf_conf_proto protoreflect.FileDescriptor +func (x *Upload_Local) Reset() { + *x = Upload_Local{} + mi := &file_conf_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} -var file_conf_conf_proto_rawDesc = string([]byte{ - 0x0a, 0x0f, 0x63, 0x6f, 0x6e, 0x66, 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x12, 0x0a, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x1a, 0x1e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, - 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x5d, 0x0a, - 0x09, 0x42, 0x6f, 0x6f, 0x74, 0x73, 0x74, 0x72, 0x61, 0x70, 0x12, 0x2a, 0x0a, 0x06, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x6b, 0x72, 0x61, - 0x74, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x06, - 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x24, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2e, 0x61, 0x70, - 0x69, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0xb8, 0x02, 0x0a, - 0x06, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x2b, 0x0a, 0x04, 0x68, 0x74, 0x74, 0x70, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2e, 0x61, - 0x70, 0x69, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x48, 0x54, 0x54, 0x50, 0x52, 0x04, - 0x68, 0x74, 0x74, 0x70, 0x12, 0x2b, 0x0a, 0x04, 0x67, 0x72, 0x70, 0x63, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, - 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x47, 0x52, 0x50, 0x43, 0x52, 0x04, 0x67, 0x72, 0x70, - 0x63, 0x1a, 0x69, 0x0a, 0x04, 0x48, 0x54, 0x54, 0x50, 0x12, 0x18, 0x0a, 0x07, 0x6e, 0x65, 0x74, - 0x77, 0x6f, 0x72, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6e, 0x65, 0x74, 0x77, - 0x6f, 0x72, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x64, 0x64, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x61, 0x64, 0x64, 0x72, 0x12, 0x33, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, - 0x75, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x1a, 0x69, 0x0a, 0x04, - 0x47, 0x52, 0x50, 0x43, 0x12, 0x18, 0x0a, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x12, 0x12, - 0x0a, 0x04, 0x61, 0x64, 0x64, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x61, 0x64, - 0x64, 0x72, 0x12, 0x33, 0x0a, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, - 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x22, 0xdd, 0x02, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, - 0x12, 0x35, 0x0a, 0x08, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, - 0x44, 0x61, 0x74, 0x61, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x52, 0x08, 0x64, - 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x12, 0x2c, 0x0a, 0x05, 0x72, 0x65, 0x64, 0x69, 0x73, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x6b, 0x72, 0x61, 0x74, 0x6f, 0x73, 0x2e, - 0x61, 0x70, 0x69, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x2e, 0x52, 0x65, 0x64, 0x69, 0x73, 0x52, 0x05, - 0x72, 0x65, 0x64, 0x69, 0x73, 0x1a, 0x3a, 0x0a, 0x08, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, - 0x65, 0x12, 0x16, 0x0a, 0x06, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x06, 0x64, 0x72, 0x69, 0x76, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x1a, 0xb3, 0x01, 0x0a, 0x05, 0x52, 0x65, 0x64, 0x69, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6e, - 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6e, 0x65, - 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x64, 0x64, 0x72, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x61, 0x64, 0x64, 0x72, 0x12, 0x3c, 0x0a, 0x0c, 0x72, 0x65, 0x61, - 0x64, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x72, 0x65, 0x61, 0x64, - 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x12, 0x3e, 0x0a, 0x0d, 0x77, 0x72, 0x69, 0x74, 0x65, - 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x77, 0x72, 0x69, 0x74, 0x65, - 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x42, 0x21, 0x5a, 0x1f, 0x6b, 0x72, 0x61, 0x74, 0x6f, - 0x73, 0x2d, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, - 0x2f, 0x63, 0x6f, 0x6e, 0x66, 0x3b, 0x63, 0x6f, 0x6e, 0x66, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, -}) +func (x *Upload_Local) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Upload_Local) ProtoMessage() {} + +func (x *Upload_Local) ProtoReflect() protoreflect.Message { + mi := &file_conf_proto_msgTypes[11] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Upload_Local.ProtoReflect.Descriptor instead. +func (*Upload_Local) Descriptor() ([]byte, []int) { + return file_conf_proto_rawDescGZIP(), []int{6, 0} +} + +func (x *Upload_Local) GetStorePath() string { + if x != nil { + return x.StorePath + } + return "" +} + +type Upload_Aliyun struct { + state protoimpl.MessageState `protogen:"open.v1"` + Endpoint string `protobuf:"bytes,1,opt,name=endpoint,proto3" json:"endpoint,omitempty"` + AccessKeyId string `protobuf:"bytes,2,opt,name=access_key_id,json=accessKeyId,proto3" json:"access_key_id,omitempty"` + AccessKeySecret string `protobuf:"bytes,3,opt,name=access_key_secret,json=accessKeySecret,proto3" json:"access_key_secret,omitempty"` + BucketName string `protobuf:"bytes,4,opt,name=bucket_name,json=bucketName,proto3" json:"bucket_name,omitempty"` + BucketUrl string `protobuf:"bytes,5,opt,name=bucket_url,json=bucketUrl,proto3" json:"bucket_url,omitempty"` + BasePath string `protobuf:"bytes,6,opt,name=base_path,json=basePath,proto3" json:"base_path,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Upload_Aliyun) Reset() { + *x = Upload_Aliyun{} + mi := &file_conf_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Upload_Aliyun) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Upload_Aliyun) ProtoMessage() {} + +func (x *Upload_Aliyun) ProtoReflect() protoreflect.Message { + mi := &file_conf_proto_msgTypes[12] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Upload_Aliyun.ProtoReflect.Descriptor instead. +func (*Upload_Aliyun) Descriptor() ([]byte, []int) { + return file_conf_proto_rawDescGZIP(), []int{6, 1} +} + +func (x *Upload_Aliyun) GetEndpoint() string { + if x != nil { + return x.Endpoint + } + return "" +} + +func (x *Upload_Aliyun) GetAccessKeyId() string { + if x != nil { + return x.AccessKeyId + } + return "" +} + +func (x *Upload_Aliyun) GetAccessKeySecret() string { + if x != nil { + return x.AccessKeySecret + } + return "" +} + +func (x *Upload_Aliyun) GetBucketName() string { + if x != nil { + return x.BucketName + } + return "" +} + +func (x *Upload_Aliyun) GetBucketUrl() string { + if x != nil { + return x.BucketUrl + } + return "" +} + +func (x *Upload_Aliyun) GetBasePath() string { + if x != nil { + return x.BasePath + } + return "" +} + +type Upload_Tencent struct { + state protoimpl.MessageState `protogen:"open.v1"` + Bucket string `protobuf:"bytes,1,opt,name=bucket,proto3" json:"bucket,omitempty"` + Region string `protobuf:"bytes,2,opt,name=region,proto3" json:"region,omitempty"` + SecretId string `protobuf:"bytes,3,opt,name=secret_id,json=secretId,proto3" json:"secret_id,omitempty"` + SecretKey string `protobuf:"bytes,4,opt,name=secret_key,json=secretKey,proto3" json:"secret_key,omitempty"` + BaseUrl string `protobuf:"bytes,5,opt,name=base_url,json=baseUrl,proto3" json:"base_url,omitempty"` + PathPrefix string `protobuf:"bytes,6,opt,name=path_prefix,json=pathPrefix,proto3" json:"path_prefix,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Upload_Tencent) Reset() { + *x = Upload_Tencent{} + mi := &file_conf_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Upload_Tencent) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Upload_Tencent) ProtoMessage() {} + +func (x *Upload_Tencent) ProtoReflect() protoreflect.Message { + mi := &file_conf_proto_msgTypes[13] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Upload_Tencent.ProtoReflect.Descriptor instead. +func (*Upload_Tencent) Descriptor() ([]byte, []int) { + return file_conf_proto_rawDescGZIP(), []int{6, 2} +} + +func (x *Upload_Tencent) GetBucket() string { + if x != nil { + return x.Bucket + } + return "" +} + +func (x *Upload_Tencent) GetRegion() string { + if x != nil { + return x.Region + } + return "" +} + +func (x *Upload_Tencent) GetSecretId() string { + if x != nil { + return x.SecretId + } + return "" +} + +func (x *Upload_Tencent) GetSecretKey() string { + if x != nil { + return x.SecretKey + } + return "" +} + +func (x *Upload_Tencent) GetBaseUrl() string { + if x != nil { + return x.BaseUrl + } + return "" +} + +func (x *Upload_Tencent) GetPathPrefix() string { + if x != nil { + return x.PathPrefix + } + return "" +} + +type Upload_Qiniu struct { + state protoimpl.MessageState `protogen:"open.v1"` + Zone string `protobuf:"bytes,1,opt,name=zone,proto3" json:"zone,omitempty"` + Bucket string `protobuf:"bytes,2,opt,name=bucket,proto3" json:"bucket,omitempty"` + ImgPath string `protobuf:"bytes,3,opt,name=img_path,json=imgPath,proto3" json:"img_path,omitempty"` + AccessKey string `protobuf:"bytes,4,opt,name=access_key,json=accessKey,proto3" json:"access_key,omitempty"` + SecretKey string `protobuf:"bytes,5,opt,name=secret_key,json=secretKey,proto3" json:"secret_key,omitempty"` + UseHttps bool `protobuf:"varint,6,opt,name=use_https,json=useHttps,proto3" json:"use_https,omitempty"` + UseCdnDomains bool `protobuf:"varint,7,opt,name=use_cdn_domains,json=useCdnDomains,proto3" json:"use_cdn_domains,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Upload_Qiniu) Reset() { + *x = Upload_Qiniu{} + mi := &file_conf_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Upload_Qiniu) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Upload_Qiniu) ProtoMessage() {} + +func (x *Upload_Qiniu) ProtoReflect() protoreflect.Message { + mi := &file_conf_proto_msgTypes[14] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Upload_Qiniu.ProtoReflect.Descriptor instead. +func (*Upload_Qiniu) Descriptor() ([]byte, []int) { + return file_conf_proto_rawDescGZIP(), []int{6, 3} +} + +func (x *Upload_Qiniu) GetZone() string { + if x != nil { + return x.Zone + } + return "" +} + +func (x *Upload_Qiniu) GetBucket() string { + if x != nil { + return x.Bucket + } + return "" +} + +func (x *Upload_Qiniu) GetImgPath() string { + if x != nil { + return x.ImgPath + } + return "" +} + +func (x *Upload_Qiniu) GetAccessKey() string { + if x != nil { + return x.AccessKey + } + return "" +} + +func (x *Upload_Qiniu) GetSecretKey() string { + if x != nil { + return x.SecretKey + } + return "" +} + +func (x *Upload_Qiniu) GetUseHttps() bool { + if x != nil { + return x.UseHttps + } + return false +} + +func (x *Upload_Qiniu) GetUseCdnDomains() bool { + if x != nil { + return x.UseCdnDomains + } + return false +} + +type Upload_Minio struct { + state protoimpl.MessageState `protogen:"open.v1"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` + Secret string `protobuf:"bytes,2,opt,name=secret,proto3" json:"secret,omitempty"` + Bucket string `protobuf:"bytes,3,opt,name=bucket,proto3" json:"bucket,omitempty"` + Endpoint string `protobuf:"bytes,4,opt,name=endpoint,proto3" json:"endpoint,omitempty"` + BasePath string `protobuf:"bytes,5,opt,name=base_path,json=basePath,proto3" json:"base_path,omitempty"` + UseSsl bool `protobuf:"varint,6,opt,name=use_ssl,json=useSsl,proto3" json:"use_ssl,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Upload_Minio) Reset() { + *x = Upload_Minio{} + mi := &file_conf_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Upload_Minio) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Upload_Minio) ProtoMessage() {} + +func (x *Upload_Minio) ProtoReflect() protoreflect.Message { + mi := &file_conf_proto_msgTypes[15] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Upload_Minio.ProtoReflect.Descriptor instead. +func (*Upload_Minio) Descriptor() ([]byte, []int) { + return file_conf_proto_rawDescGZIP(), []int{6, 4} +} + +func (x *Upload_Minio) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *Upload_Minio) GetSecret() string { + if x != nil { + return x.Secret + } + return "" +} + +func (x *Upload_Minio) GetBucket() string { + if x != nil { + return x.Bucket + } + return "" +} + +func (x *Upload_Minio) GetEndpoint() string { + if x != nil { + return x.Endpoint + } + return "" +} + +func (x *Upload_Minio) GetBasePath() string { + if x != nil { + return x.BasePath + } + return "" +} + +func (x *Upload_Minio) GetUseSsl() bool { + if x != nil { + return x.UseSsl + } + return false +} + +type Upload_AwsS3 struct { + state protoimpl.MessageState `protogen:"open.v1"` + Bucket string `protobuf:"bytes,1,opt,name=bucket,proto3" json:"bucket,omitempty"` + Region string `protobuf:"bytes,2,opt,name=region,proto3" json:"region,omitempty"` + Endpoint string `protobuf:"bytes,3,opt,name=endpoint,proto3" json:"endpoint,omitempty"` + SecretId string `protobuf:"bytes,4,opt,name=secret_id,json=secretId,proto3" json:"secret_id,omitempty"` + SecretKey string `protobuf:"bytes,5,opt,name=secret_key,json=secretKey,proto3" json:"secret_key,omitempty"` + BaseUrl string `protobuf:"bytes,6,opt,name=base_url,json=baseUrl,proto3" json:"base_url,omitempty"` + PathPrefix string `protobuf:"bytes,7,opt,name=path_prefix,json=pathPrefix,proto3" json:"path_prefix,omitempty"` + S3ForcePathStyle bool `protobuf:"varint,8,opt,name=s3_force_path_style,json=s3ForcePathStyle,proto3" json:"s3_force_path_style,omitempty"` + DisableSsl bool `protobuf:"varint,9,opt,name=disable_ssl,json=disableSsl,proto3" json:"disable_ssl,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Upload_AwsS3) Reset() { + *x = Upload_AwsS3{} + mi := &file_conf_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Upload_AwsS3) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Upload_AwsS3) ProtoMessage() {} + +func (x *Upload_AwsS3) ProtoReflect() protoreflect.Message { + mi := &file_conf_proto_msgTypes[16] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Upload_AwsS3.ProtoReflect.Descriptor instead. +func (*Upload_AwsS3) Descriptor() ([]byte, []int) { + return file_conf_proto_rawDescGZIP(), []int{6, 5} +} + +func (x *Upload_AwsS3) GetBucket() string { + if x != nil { + return x.Bucket + } + return "" +} + +func (x *Upload_AwsS3) GetRegion() string { + if x != nil { + return x.Region + } + return "" +} + +func (x *Upload_AwsS3) GetEndpoint() string { + if x != nil { + return x.Endpoint + } + return "" +} + +func (x *Upload_AwsS3) GetSecretId() string { + if x != nil { + return x.SecretId + } + return "" +} + +func (x *Upload_AwsS3) GetSecretKey() string { + if x != nil { + return x.SecretKey + } + return "" +} + +func (x *Upload_AwsS3) GetBaseUrl() string { + if x != nil { + return x.BaseUrl + } + return "" +} + +func (x *Upload_AwsS3) GetPathPrefix() string { + if x != nil { + return x.PathPrefix + } + return "" +} + +func (x *Upload_AwsS3) GetS3ForcePathStyle() bool { + if x != nil { + return x.S3ForcePathStyle + } + return false +} + +func (x *Upload_AwsS3) GetDisableSsl() bool { + if x != nil { + return x.DisableSsl + } + return false +} + +type Upload_HuaweiObs struct { + state protoimpl.MessageState `protogen:"open.v1"` + Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` + Bucket string `protobuf:"bytes,2,opt,name=bucket,proto3" json:"bucket,omitempty"` + Endpoint string `protobuf:"bytes,3,opt,name=endpoint,proto3" json:"endpoint,omitempty"` + AccessKey string `protobuf:"bytes,4,opt,name=access_key,json=accessKey,proto3" json:"access_key,omitempty"` + SecretKey string `protobuf:"bytes,5,opt,name=secret_key,json=secretKey,proto3" json:"secret_key,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Upload_HuaweiObs) Reset() { + *x = Upload_HuaweiObs{} + mi := &file_conf_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Upload_HuaweiObs) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Upload_HuaweiObs) ProtoMessage() {} + +func (x *Upload_HuaweiObs) ProtoReflect() protoreflect.Message { + mi := &file_conf_proto_msgTypes[17] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Upload_HuaweiObs.ProtoReflect.Descriptor instead. +func (*Upload_HuaweiObs) Descriptor() ([]byte, []int) { + return file_conf_proto_rawDescGZIP(), []int{6, 6} +} + +func (x *Upload_HuaweiObs) GetPath() string { + if x != nil { + return x.Path + } + return "" +} + +func (x *Upload_HuaweiObs) GetBucket() string { + if x != nil { + return x.Bucket + } + return "" +} + +func (x *Upload_HuaweiObs) GetEndpoint() string { + if x != nil { + return x.Endpoint + } + return "" +} + +func (x *Upload_HuaweiObs) GetAccessKey() string { + if x != nil { + return x.AccessKey + } + return "" +} + +func (x *Upload_HuaweiObs) GetSecretKey() string { + if x != nil { + return x.SecretKey + } + return "" +} + +type Upload_CloudflareR2 struct { + state protoimpl.MessageState `protogen:"open.v1"` + Bucket string `protobuf:"bytes,1,opt,name=bucket,proto3" json:"bucket,omitempty"` + BaseUrl string `protobuf:"bytes,2,opt,name=base_url,json=baseUrl,proto3" json:"base_url,omitempty"` + Path string `protobuf:"bytes,3,opt,name=path,proto3" json:"path,omitempty"` + AccountId string `protobuf:"bytes,4,opt,name=account_id,json=accountId,proto3" json:"account_id,omitempty"` + AccessKeyId string `protobuf:"bytes,5,opt,name=access_key_id,json=accessKeyId,proto3" json:"access_key_id,omitempty"` + SecretAccessKey string `protobuf:"bytes,6,opt,name=secret_access_key,json=secretAccessKey,proto3" json:"secret_access_key,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *Upload_CloudflareR2) Reset() { + *x = Upload_CloudflareR2{} + mi := &file_conf_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *Upload_CloudflareR2) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Upload_CloudflareR2) ProtoMessage() {} + +func (x *Upload_CloudflareR2) ProtoReflect() protoreflect.Message { + mi := &file_conf_proto_msgTypes[18] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Upload_CloudflareR2.ProtoReflect.Descriptor instead. +func (*Upload_CloudflareR2) Descriptor() ([]byte, []int) { + return file_conf_proto_rawDescGZIP(), []int{6, 7} +} + +func (x *Upload_CloudflareR2) GetBucket() string { + if x != nil { + return x.Bucket + } + return "" +} + +func (x *Upload_CloudflareR2) GetBaseUrl() string { + if x != nil { + return x.BaseUrl + } + return "" +} + +func (x *Upload_CloudflareR2) GetPath() string { + if x != nil { + return x.Path + } + return "" +} + +func (x *Upload_CloudflareR2) GetAccountId() string { + if x != nil { + return x.AccountId + } + return "" +} + +func (x *Upload_CloudflareR2) GetAccessKeyId() string { + if x != nil { + return x.AccessKeyId + } + return "" +} + +func (x *Upload_CloudflareR2) GetSecretAccessKey() string { + if x != nil { + return x.SecretAccessKey + } + return "" +} + +var File_conf_proto protoreflect.FileDescriptor + +const file_conf_proto_rawDesc = "" + + "\n" + + "\n" + + "conf.proto\x12\n" + + "kratos.api\x1a\x1egoogle/protobuf/duration.proto\"\x87\x02\n" + + "\tBootstrap\x12*\n" + + "\x06server\x18\x01 \x01(\v2\x12.kratos.api.ServerR\x06server\x12$\n" + + "\x04data\x18\x02 \x01(\v2\x10.kratos.api.DataR\x04data\x12!\n" + + "\x03jwt\x18\x03 \x01(\v2\x0f.kratos.api.JWTR\x03jwt\x12*\n" + + "\x06casbin\x18\x04 \x01(\v2\x12.kratos.api.CasbinR\x06casbin\x12-\n" + + "\acaptcha\x18\x05 \x01(\v2\x13.kratos.api.CaptchaR\acaptcha\x12*\n" + + "\x06upload\x18\x06 \x01(\v2\x12.kratos.api.UploadR\x06upload\"\xb8\x02\n" + + "\x06Server\x12+\n" + + "\x04http\x18\x01 \x01(\v2\x17.kratos.api.Server.HTTPR\x04http\x12+\n" + + "\x04grpc\x18\x02 \x01(\v2\x17.kratos.api.Server.GRPCR\x04grpc\x1ai\n" + + "\x04HTTP\x12\x18\n" + + "\anetwork\x18\x01 \x01(\tR\anetwork\x12\x12\n" + + "\x04addr\x18\x02 \x01(\tR\x04addr\x123\n" + + "\atimeout\x18\x03 \x01(\v2\x19.google.protobuf.DurationR\atimeout\x1ai\n" + + "\x04GRPC\x12\x18\n" + + "\anetwork\x18\x01 \x01(\tR\anetwork\x12\x12\n" + + "\x04addr\x18\x02 \x01(\tR\x04addr\x123\n" + + "\atimeout\x18\x03 \x01(\v2\x19.google.protobuf.DurationR\atimeout\"\xe5\x03\n" + + "\x04Data\x125\n" + + "\bdatabase\x18\x01 \x01(\v2\x19.kratos.api.Data.DatabaseR\bdatabase\x12,\n" + + "\x05redis\x18\x02 \x01(\v2\x16.kratos.api.Data.RedisR\x05redis\x1a\xe7\x01\n" + + "\bDatabase\x12\x16\n" + + "\x06driver\x18\x01 \x01(\tR\x06driver\x12\x16\n" + + "\x06source\x18\x02 \x01(\tR\x06source\x12!\n" + + "\ftable_prefix\x18\x03 \x01(\tR\vtablePrefix\x12$\n" + + "\x0emax_idle_conns\x18\x04 \x01(\x05R\fmaxIdleConns\x12$\n" + + "\x0emax_open_conns\x18\x05 \x01(\x05R\fmaxOpenConns\x12!\n" + + "\fmax_lifetime\x18\x06 \x01(\x05R\vmaxLifetime\x12\x19\n" + + "\blog_mode\x18\a \x01(\bR\alogMode\x1a\x8d\x01\n" + + "\x05Redis\x12\x12\n" + + "\x04addr\x18\x01 \x01(\tR\x04addr\x12\x1a\n" + + "\bpassword\x18\x02 \x01(\tR\bpassword\x12\x0e\n" + + "\x02db\x18\x03 \x01(\x05R\x02db\x12\x1f\n" + + "\vuse_cluster\x18\x04 \x01(\bR\n" + + "useCluster\x12#\n" + + "\rcluster_addrs\x18\x05 \x03(\tR\fclusterAddrs\"\x82\x01\n" + + "\x03JWT\x12\x1f\n" + + "\vsigning_key\x18\x01 \x01(\tR\n" + + "signingKey\x12!\n" + + "\fexpires_time\x18\x02 \x01(\tR\vexpiresTime\x12\x1f\n" + + "\vbuffer_time\x18\x03 \x01(\tR\n" + + "bufferTime\x12\x16\n" + + "\x06issuer\x18\x04 \x01(\tR\x06issuer\"'\n" + + "\x06Casbin\x12\x1d\n" + + "\n" + + "model_path\x18\x01 \x01(\tR\tmodelPath\"\xb5\x01\n" + + "\aCaptcha\x12\x19\n" + + "\bkey_long\x18\x01 \x01(\x05R\akeyLong\x12\x1b\n" + + "\timg_width\x18\x02 \x01(\x05R\bimgWidth\x12\x1d\n" + + "\n" + + "img_height\x18\x03 \x01(\x05R\timgHeight\x12!\n" + + "\fopen_captcha\x18\x04 \x01(\x05R\vopenCaptcha\x120\n" + + "\x14open_captcha_timeout\x18\x05 \x01(\x05R\x12openCaptchaTimeout\"\x91\x0f\n" + + "\x06Upload\x12\x12\n" + + "\x04type\x18\x01 \x01(\tR\x04type\x12\x12\n" + + "\x04path\x18\x02 \x01(\tR\x04path\x12\x19\n" + + "\bmax_size\x18\x03 \x01(\x03R\amaxSize\x12.\n" + + "\x05local\x18\x04 \x01(\v2\x18.kratos.api.Upload.LocalR\x05local\x121\n" + + "\x06aliyun\x18\x05 \x01(\v2\x19.kratos.api.Upload.AliyunR\x06aliyun\x124\n" + + "\atencent\x18\x06 \x01(\v2\x1a.kratos.api.Upload.TencentR\atencent\x12.\n" + + "\x05qiniu\x18\a \x01(\v2\x18.kratos.api.Upload.QiniuR\x05qiniu\x12.\n" + + "\x05minio\x18\b \x01(\v2\x18.kratos.api.Upload.MinioR\x05minio\x12/\n" + + "\x06aws_s3\x18\t \x01(\v2\x18.kratos.api.Upload.AwsS3R\x05awsS3\x12;\n" + + "\n" + + "huawei_obs\x18\n" + + " \x01(\v2\x1c.kratos.api.Upload.HuaweiObsR\thuaweiObs\x12D\n" + + "\rcloudflare_r2\x18\v \x01(\v2\x1f.kratos.api.Upload.CloudflareR2R\fcloudflareR2\x1a&\n" + + "\x05Local\x12\x1d\n" + + "\n" + + "store_path\x18\x01 \x01(\tR\tstorePath\x1a\xd1\x01\n" + + "\x06Aliyun\x12\x1a\n" + + "\bendpoint\x18\x01 \x01(\tR\bendpoint\x12\"\n" + + "\raccess_key_id\x18\x02 \x01(\tR\vaccessKeyId\x12*\n" + + "\x11access_key_secret\x18\x03 \x01(\tR\x0faccessKeySecret\x12\x1f\n" + + "\vbucket_name\x18\x04 \x01(\tR\n" + + "bucketName\x12\x1d\n" + + "\n" + + "bucket_url\x18\x05 \x01(\tR\tbucketUrl\x12\x1b\n" + + "\tbase_path\x18\x06 \x01(\tR\bbasePath\x1a\xb1\x01\n" + + "\aTencent\x12\x16\n" + + "\x06bucket\x18\x01 \x01(\tR\x06bucket\x12\x16\n" + + "\x06region\x18\x02 \x01(\tR\x06region\x12\x1b\n" + + "\tsecret_id\x18\x03 \x01(\tR\bsecretId\x12\x1d\n" + + "\n" + + "secret_key\x18\x04 \x01(\tR\tsecretKey\x12\x19\n" + + "\bbase_url\x18\x05 \x01(\tR\abaseUrl\x12\x1f\n" + + "\vpath_prefix\x18\x06 \x01(\tR\n" + + "pathPrefix\x1a\xd1\x01\n" + + "\x05Qiniu\x12\x12\n" + + "\x04zone\x18\x01 \x01(\tR\x04zone\x12\x16\n" + + "\x06bucket\x18\x02 \x01(\tR\x06bucket\x12\x19\n" + + "\bimg_path\x18\x03 \x01(\tR\aimgPath\x12\x1d\n" + + "\n" + + "access_key\x18\x04 \x01(\tR\taccessKey\x12\x1d\n" + + "\n" + + "secret_key\x18\x05 \x01(\tR\tsecretKey\x12\x1b\n" + + "\tuse_https\x18\x06 \x01(\bR\buseHttps\x12&\n" + + "\x0fuse_cdn_domains\x18\a \x01(\bR\ruseCdnDomains\x1a\x99\x01\n" + + "\x05Minio\x12\x0e\n" + + "\x02id\x18\x01 \x01(\tR\x02id\x12\x16\n" + + "\x06secret\x18\x02 \x01(\tR\x06secret\x12\x16\n" + + "\x06bucket\x18\x03 \x01(\tR\x06bucket\x12\x1a\n" + + "\bendpoint\x18\x04 \x01(\tR\bendpoint\x12\x1b\n" + + "\tbase_path\x18\x05 \x01(\tR\bbasePath\x12\x17\n" + + "\ause_ssl\x18\x06 \x01(\bR\x06useSsl\x1a\x9b\x02\n" + + "\x05AwsS3\x12\x16\n" + + "\x06bucket\x18\x01 \x01(\tR\x06bucket\x12\x16\n" + + "\x06region\x18\x02 \x01(\tR\x06region\x12\x1a\n" + + "\bendpoint\x18\x03 \x01(\tR\bendpoint\x12\x1b\n" + + "\tsecret_id\x18\x04 \x01(\tR\bsecretId\x12\x1d\n" + + "\n" + + "secret_key\x18\x05 \x01(\tR\tsecretKey\x12\x19\n" + + "\bbase_url\x18\x06 \x01(\tR\abaseUrl\x12\x1f\n" + + "\vpath_prefix\x18\a \x01(\tR\n" + + "pathPrefix\x12-\n" + + "\x13s3_force_path_style\x18\b \x01(\bR\x10s3ForcePathStyle\x12\x1f\n" + + "\vdisable_ssl\x18\t \x01(\bR\n" + + "disableSsl\x1a\x91\x01\n" + + "\tHuaweiObs\x12\x12\n" + + "\x04path\x18\x01 \x01(\tR\x04path\x12\x16\n" + + "\x06bucket\x18\x02 \x01(\tR\x06bucket\x12\x1a\n" + + "\bendpoint\x18\x03 \x01(\tR\bendpoint\x12\x1d\n" + + "\n" + + "access_key\x18\x04 \x01(\tR\taccessKey\x12\x1d\n" + + "\n" + + "secret_key\x18\x05 \x01(\tR\tsecretKey\x1a\xc4\x01\n" + + "\fCloudflareR2\x12\x16\n" + + "\x06bucket\x18\x01 \x01(\tR\x06bucket\x12\x19\n" + + "\bbase_url\x18\x02 \x01(\tR\abaseUrl\x12\x12\n" + + "\x04path\x18\x03 \x01(\tR\x04path\x12\x1d\n" + + "\n" + + "account_id\x18\x04 \x01(\tR\taccountId\x12\"\n" + + "\raccess_key_id\x18\x05 \x01(\tR\vaccessKeyId\x12*\n" + + "\x11secret_access_key\x18\x06 \x01(\tR\x0fsecretAccessKeyB\x18Z\x16kra/internal/conf;confb\x06proto3" var ( - file_conf_conf_proto_rawDescOnce sync.Once - file_conf_conf_proto_rawDescData []byte + file_conf_proto_rawDescOnce sync.Once + file_conf_proto_rawDescData []byte ) -func file_conf_conf_proto_rawDescGZIP() []byte { - file_conf_conf_proto_rawDescOnce.Do(func() { - file_conf_conf_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_conf_conf_proto_rawDesc), len(file_conf_conf_proto_rawDesc))) +func file_conf_proto_rawDescGZIP() []byte { + file_conf_proto_rawDescOnce.Do(func() { + file_conf_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_conf_proto_rawDesc), len(file_conf_proto_rawDesc))) }) - return file_conf_conf_proto_rawDescData + return file_conf_proto_rawDescData } -var file_conf_conf_proto_msgTypes = make([]protoimpl.MessageInfo, 7) -var file_conf_conf_proto_goTypes = []any{ +var file_conf_proto_msgTypes = make([]protoimpl.MessageInfo, 19) +var file_conf_proto_goTypes = []any{ (*Bootstrap)(nil), // 0: kratos.api.Bootstrap (*Server)(nil), // 1: kratos.api.Server (*Data)(nil), // 2: kratos.api.Data - (*Server_HTTP)(nil), // 3: kratos.api.Server.HTTP - (*Server_GRPC)(nil), // 4: kratos.api.Server.GRPC - (*Data_Database)(nil), // 5: kratos.api.Data.Database - (*Data_Redis)(nil), // 6: kratos.api.Data.Redis - (*durationpb.Duration)(nil), // 7: google.protobuf.Duration + (*JWT)(nil), // 3: kratos.api.JWT + (*Casbin)(nil), // 4: kratos.api.Casbin + (*Captcha)(nil), // 5: kratos.api.Captcha + (*Upload)(nil), // 6: kratos.api.Upload + (*Server_HTTP)(nil), // 7: kratos.api.Server.HTTP + (*Server_GRPC)(nil), // 8: kratos.api.Server.GRPC + (*Data_Database)(nil), // 9: kratos.api.Data.Database + (*Data_Redis)(nil), // 10: kratos.api.Data.Redis + (*Upload_Local)(nil), // 11: kratos.api.Upload.Local + (*Upload_Aliyun)(nil), // 12: kratos.api.Upload.Aliyun + (*Upload_Tencent)(nil), // 13: kratos.api.Upload.Tencent + (*Upload_Qiniu)(nil), // 14: kratos.api.Upload.Qiniu + (*Upload_Minio)(nil), // 15: kratos.api.Upload.Minio + (*Upload_AwsS3)(nil), // 16: kratos.api.Upload.AwsS3 + (*Upload_HuaweiObs)(nil), // 17: kratos.api.Upload.HuaweiObs + (*Upload_CloudflareR2)(nil), // 18: kratos.api.Upload.CloudflareR2 + (*durationpb.Duration)(nil), // 19: google.protobuf.Duration } -var file_conf_conf_proto_depIdxs = []int32{ +var file_conf_proto_depIdxs = []int32{ 1, // 0: kratos.api.Bootstrap.server:type_name -> kratos.api.Server 2, // 1: kratos.api.Bootstrap.data:type_name -> kratos.api.Data - 3, // 2: kratos.api.Server.http:type_name -> kratos.api.Server.HTTP - 4, // 3: kratos.api.Server.grpc:type_name -> kratos.api.Server.GRPC - 5, // 4: kratos.api.Data.database:type_name -> kratos.api.Data.Database - 6, // 5: kratos.api.Data.redis:type_name -> kratos.api.Data.Redis - 7, // 6: kratos.api.Server.HTTP.timeout:type_name -> google.protobuf.Duration - 7, // 7: kratos.api.Server.GRPC.timeout:type_name -> google.protobuf.Duration - 7, // 8: kratos.api.Data.Redis.read_timeout:type_name -> google.protobuf.Duration - 7, // 9: kratos.api.Data.Redis.write_timeout:type_name -> google.protobuf.Duration - 10, // [10:10] is the sub-list for method output_type - 10, // [10:10] is the sub-list for method input_type - 10, // [10:10] is the sub-list for extension type_name - 10, // [10:10] is the sub-list for extension extendee - 0, // [0:10] is the sub-list for field type_name + 3, // 2: kratos.api.Bootstrap.jwt:type_name -> kratos.api.JWT + 4, // 3: kratos.api.Bootstrap.casbin:type_name -> kratos.api.Casbin + 5, // 4: kratos.api.Bootstrap.captcha:type_name -> kratos.api.Captcha + 6, // 5: kratos.api.Bootstrap.upload:type_name -> kratos.api.Upload + 7, // 6: kratos.api.Server.http:type_name -> kratos.api.Server.HTTP + 8, // 7: kratos.api.Server.grpc:type_name -> kratos.api.Server.GRPC + 9, // 8: kratos.api.Data.database:type_name -> kratos.api.Data.Database + 10, // 9: kratos.api.Data.redis:type_name -> kratos.api.Data.Redis + 11, // 10: kratos.api.Upload.local:type_name -> kratos.api.Upload.Local + 12, // 11: kratos.api.Upload.aliyun:type_name -> kratos.api.Upload.Aliyun + 13, // 12: kratos.api.Upload.tencent:type_name -> kratos.api.Upload.Tencent + 14, // 13: kratos.api.Upload.qiniu:type_name -> kratos.api.Upload.Qiniu + 15, // 14: kratos.api.Upload.minio:type_name -> kratos.api.Upload.Minio + 16, // 15: kratos.api.Upload.aws_s3:type_name -> kratos.api.Upload.AwsS3 + 17, // 16: kratos.api.Upload.huawei_obs:type_name -> kratos.api.Upload.HuaweiObs + 18, // 17: kratos.api.Upload.cloudflare_r2:type_name -> kratos.api.Upload.CloudflareR2 + 19, // 18: kratos.api.Server.HTTP.timeout:type_name -> google.protobuf.Duration + 19, // 19: kratos.api.Server.GRPC.timeout:type_name -> google.protobuf.Duration + 20, // [20:20] is the sub-list for method output_type + 20, // [20:20] is the sub-list for method input_type + 20, // [20:20] is the sub-list for extension type_name + 20, // [20:20] is the sub-list for extension extendee + 0, // [0:20] is the sub-list for field type_name } -func init() { file_conf_conf_proto_init() } -func file_conf_conf_proto_init() { - if File_conf_conf_proto != nil { +func init() { file_conf_proto_init() } +func file_conf_proto_init() { + if File_conf_proto != nil { return } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: unsafe.Slice(unsafe.StringData(file_conf_conf_proto_rawDesc), len(file_conf_conf_proto_rawDesc)), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_conf_proto_rawDesc), len(file_conf_proto_rawDesc)), NumEnums: 0, - NumMessages: 7, + NumMessages: 19, NumExtensions: 0, NumServices: 0, }, - GoTypes: file_conf_conf_proto_goTypes, - DependencyIndexes: file_conf_conf_proto_depIdxs, - MessageInfos: file_conf_conf_proto_msgTypes, + GoTypes: file_conf_proto_goTypes, + DependencyIndexes: file_conf_proto_depIdxs, + MessageInfos: file_conf_proto_msgTypes, }.Build() - File_conf_conf_proto = out.File - file_conf_conf_proto_goTypes = nil - file_conf_conf_proto_depIdxs = nil + File_conf_proto = out.File + file_conf_proto_goTypes = nil + file_conf_proto_depIdxs = nil } diff --git a/internal/conf/conf.proto b/internal/conf/conf.proto index e1de5d2..5b7e485 100644 --- a/internal/conf/conf.proto +++ b/internal/conf/conf.proto @@ -1,13 +1,17 @@ syntax = "proto3"; package kratos.api; -option go_package = "kratos-admin/internal/conf;conf"; +option go_package = "kra/internal/conf;conf"; import "google/protobuf/duration.proto"; message Bootstrap { Server server = 1; Data data = 2; + JWT jwt = 3; + Casbin casbin = 4; + Captcha captcha = 5; + Upload upload = 6; } message Server { @@ -29,13 +33,116 @@ message Data { message Database { string driver = 1; string source = 2; + string table_prefix = 3; + int32 max_idle_conns = 4; + int32 max_open_conns = 5; + int32 max_lifetime = 6; + bool log_mode = 7; } message Redis { - string network = 1; - string addr = 2; - google.protobuf.Duration read_timeout = 3; - google.protobuf.Duration write_timeout = 4; + string addr = 1; + string password = 2; + int32 db = 3; + bool use_cluster = 4; + repeated string cluster_addrs = 5; } Database database = 1; Redis redis = 2; } + +message JWT { + string signing_key = 1; + string expires_time = 2; + string buffer_time = 3; + string issuer = 4; +} + +message Casbin { + string model_path = 1; +} + +message Captcha { + int32 key_long = 1; + int32 img_width = 2; + int32 img_height = 3; + int32 open_captcha = 4; + int32 open_captcha_timeout = 5; +} + +message Upload { + string type = 1; + string path = 2; + int64 max_size = 3; + + message Local { + string store_path = 1; + } + message Aliyun { + string endpoint = 1; + string access_key_id = 2; + string access_key_secret = 3; + string bucket_name = 4; + string bucket_url = 5; + string base_path = 6; + } + message Tencent { + string bucket = 1; + string region = 2; + string secret_id = 3; + string secret_key = 4; + string base_url = 5; + string path_prefix = 6; + } + message Qiniu { + string zone = 1; + string bucket = 2; + string img_path = 3; + string access_key = 4; + string secret_key = 5; + bool use_https = 6; + bool use_cdn_domains = 7; + } + message Minio { + string id = 1; + string secret = 2; + string bucket = 3; + string endpoint = 4; + string base_path = 5; + bool use_ssl = 6; + } + message AwsS3 { + string bucket = 1; + string region = 2; + string endpoint = 3; + string secret_id = 4; + string secret_key = 5; + string base_url = 6; + string path_prefix = 7; + bool s3_force_path_style = 8; + bool disable_ssl = 9; + } + message HuaweiObs { + string path = 1; + string bucket = 2; + string endpoint = 3; + string access_key = 4; + string secret_key = 5; + } + message CloudflareR2 { + string bucket = 1; + string base_url = 2; + string path = 3; + string account_id = 4; + string access_key_id = 5; + string secret_access_key = 6; + } + + Local local = 4; + Aliyun aliyun = 5; + Tencent tencent = 6; + Qiniu qiniu = 7; + Minio minio = 8; + AwsS3 aws_s3 = 9; + HuaweiObs huawei_obs = 10; + CloudflareR2 cloudflare_r2 = 11; +} diff --git a/internal/data/gorm.go b/internal/data/gorm.go new file mode 100644 index 0000000..2067df5 --- /dev/null +++ b/internal/data/gorm.go @@ -0,0 +1,74 @@ +package data + +import ( + "time" + + "kra/internal/conf" + + "github.com/go-kratos/kratos/v2/log" + "gorm.io/driver/mysql" + "gorm.io/driver/postgres" + "gorm.io/driver/sqlite" + "gorm.io/gorm" + "gorm.io/gorm/logger" + "gorm.io/gorm/schema" +) + +// NewGormDB 创建GORM数据库连接 +func NewGormDB(c *conf.Data, l log.Logger) (*gorm.DB, func(), error) { + helper := log.NewHelper(l) + + var dialector gorm.Dialector + switch c.Database.Driver { + case "mysql": + dialector = mysql.Open(c.Database.Source) + case "postgres": + dialector = postgres.Open(c.Database.Source) + case "sqlite": + dialector = sqlite.Open(c.Database.Source) + default: + dialector = mysql.Open(c.Database.Source) + } + + gormConfig := &gorm.Config{ + NamingStrategy: schema.NamingStrategy{ + TablePrefix: c.Database.TablePrefix, + SingularTable: true, + }, + DisableForeignKeyConstraintWhenMigrating: true, + } + + // 设置日志级别 + if c.Database.LogMode { + gormConfig.Logger = logger.Default.LogMode(logger.Info) + } else { + gormConfig.Logger = logger.Default.LogMode(logger.Silent) + } + + db, err := gorm.Open(dialector, gormConfig) + if err != nil { + helper.Errorf("failed to connect database: %v", err) + return nil, nil, err + } + + sqlDB, err := db.DB() + if err != nil { + helper.Errorf("failed to get sql.DB: %v", err) + return nil, nil, err + } + + // 连接池配置 + sqlDB.SetMaxIdleConns(int(c.Database.MaxIdleConns)) + sqlDB.SetMaxOpenConns(int(c.Database.MaxOpenConns)) + sqlDB.SetConnMaxLifetime(time.Duration(c.Database.MaxLifetime) * time.Second) + + cleanup := func() { + helper.Info("closing database connection") + if err := sqlDB.Close(); err != nil { + helper.Errorf("failed to close database: %v", err) + } + } + + helper.Info("database connected successfully") + return db, cleanup, nil +} diff --git a/internal/data/model/common.go b/internal/data/model/common.go new file mode 100644 index 0000000..9068269 --- /dev/null +++ b/internal/data/model/common.go @@ -0,0 +1,30 @@ +package model + +import ( + "time" + + "gorm.io/gorm" +) + +// Model 基础模型 +type Model struct { + ID uint `gorm:"primarykey" json:"id"` + CreatedAt time.Time `json:"createdAt"` + UpdatedAt time.Time `json:"updatedAt"` + DeletedAt gorm.DeletedAt `gorm:"index" json:"-"` +} + +// PageInfo 分页请求 +type PageInfo struct { + Page int `json:"page" form:"page"` + PageSize int `json:"pageSize" form:"pageSize"` + Keyword string `json:"keyword" form:"keyword"` +} + +// PageResult 分页响应 +type PageResult struct { + List interface{} `json:"list"` + Total int64 `json:"total"` + Page int `json:"page"` + PageSize int `json:"pageSize"` +} diff --git a/internal/data/redis.go b/internal/data/redis.go new file mode 100644 index 0000000..78be53b --- /dev/null +++ b/internal/data/redis.go @@ -0,0 +1,47 @@ +package data + +import ( + "context" + + "kra/internal/conf" + + "github.com/go-kratos/kratos/v2/log" + "github.com/redis/go-redis/v9" +) + +// NewRedisClient 创建Redis客户端 +func NewRedisClient(c *conf.Data, l log.Logger) (redis.UniversalClient, func(), error) { + helper := log.NewHelper(l) + + var client redis.UniversalClient + + if c.Redis.UseCluster { + client = redis.NewClusterClient(&redis.ClusterOptions{ + Addrs: c.Redis.ClusterAddrs, + Password: c.Redis.Password, + }) + } else { + client = redis.NewClient(&redis.Options{ + Addr: c.Redis.Addr, + Password: c.Redis.Password, + DB: int(c.Redis.Db), + }) + } + + // 测试连接 + ctx := context.Background() + if _, err := client.Ping(ctx).Result(); err != nil { + helper.Errorf("failed to connect redis: %v", err) + return nil, nil, err + } + + cleanup := func() { + helper.Info("closing redis connection") + if err := client.Close(); err != nil { + helper.Errorf("failed to close redis: %v", err) + } + } + + helper.Info("redis connected successfully") + return client, cleanup, nil +} diff --git a/pkg/captcha/captcha.go b/pkg/captcha/captcha.go new file mode 100644 index 0000000..164b04e --- /dev/null +++ b/pkg/captcha/captcha.go @@ -0,0 +1,96 @@ +package captcha + +import ( + "context" + "time" + + "github.com/mojocn/base64Captcha" + "github.com/redis/go-redis/v9" +) + +// Config 验证码配置 +type Config struct { + KeyLong int + ImgWidth int + ImgHeight int + OpenCaptcha int // 0-关闭 1-开启 + OpenCaptchaTimeout int // 验证码超时时间(秒) +} + +// Captcha 验证码 +type Captcha struct { + config Config + store base64Captcha.Store +} + +// RedisStore Redis存储 +type RedisStore struct { + client redis.UniversalClient + expiration time.Duration + prefix string +} + +// NewRedisStore 创建Redis存储 +func NewRedisStore(client redis.UniversalClient, expiration time.Duration) *RedisStore { + return &RedisStore{ + client: client, + expiration: expiration, + prefix: "captcha:", + } +} + +func (s *RedisStore) Set(id string, value string) error { + return s.client.Set(context.Background(), s.prefix+id, value, s.expiration).Err() +} + +func (s *RedisStore) Get(id string, clear bool) string { + ctx := context.Background() + key := s.prefix + id + val, err := s.client.Get(ctx, key).Result() + if err != nil { + return "" + } + if clear { + s.client.Del(ctx, key) + } + return val +} + +func (s *RedisStore) Verify(id, answer string, clear bool) bool { + v := s.Get(id, clear) + return v == answer +} + +// NewCaptcha 创建验证码实例 +func NewCaptcha(config Config, store base64Captcha.Store) *Captcha { + if store == nil { + store = base64Captcha.DefaultMemStore + } + return &Captcha{ + config: config, + store: store, + } +} + +// Generate 生成验证码 +func (c *Captcha) Generate() (id, b64s, answer string, err error) { + driver := base64Captcha.NewDriverDigit( + c.config.ImgHeight, + c.config.ImgWidth, + c.config.KeyLong, + 0.7, + 80, + ) + cp := base64Captcha.NewCaptcha(driver, c.store) + return cp.Generate() +} + +// Verify 验证验证码 +func (c *Captcha) Verify(id, answer string, clear bool) bool { + return c.store.Verify(id, answer, clear) +} + +// IsOpen 是否开启验证码 +func (c *Captcha) IsOpen() bool { + return c.config.OpenCaptcha > 0 +} diff --git a/pkg/casbin/casbin.go b/pkg/casbin/casbin.go new file mode 100644 index 0000000..e7a9c2b --- /dev/null +++ b/pkg/casbin/casbin.go @@ -0,0 +1,99 @@ +package casbin + +import ( + "sync" + + "github.com/casbin/casbin/v2" + "github.com/casbin/casbin/v2/model" + gormadapter "github.com/casbin/gorm-adapter/v3" + "gorm.io/gorm" +) + +var ( + syncedCachedEnforcer *casbin.SyncedCachedEnforcer + once sync.Once +) + +// InitCasbin 初始化Casbin +func InitCasbin(db *gorm.DB, modelPath string) (*casbin.SyncedCachedEnforcer, error) { + var err error + once.Do(func() { + adapter, adapterErr := gormadapter.NewAdapterByDB(db) + if adapterErr != nil { + err = adapterErr + return + } + + var m model.Model + if modelPath != "" { + m, err = model.NewModelFromFile(modelPath) + } else { + // 默认RBAC模型 + m, err = model.NewModelFromString(` +[request_definition] +r = sub, obj, act + +[policy_definition] +p = sub, obj, act + +[role_definition] +g = _, _ + +[policy_effect] +e = some(where (p.eft == allow)) + +[matchers] +m = r.sub == p.sub && keyMatch2(r.obj,p.obj) && r.act == p.act +`) + } + if err != nil { + return + } + + syncedCachedEnforcer, err = casbin.NewSyncedCachedEnforcer(m, adapter) + if err != nil { + return + } + syncedCachedEnforcer.SetExpireTime(60 * 60) + _ = syncedCachedEnforcer.LoadPolicy() + }) + return syncedCachedEnforcer, err +} + +// GetEnforcer 获取Enforcer实例 +func GetEnforcer() *casbin.SyncedCachedEnforcer { + return syncedCachedEnforcer +} + +// CheckPermission 检查权限 +func CheckPermission(sub, obj, act string) (bool, error) { + if syncedCachedEnforcer == nil { + return false, nil + } + return syncedCachedEnforcer.Enforce(sub, obj, act) +} + +// AddPolicy 添加策略 +func AddPolicy(sub, obj, act string) (bool, error) { + return syncedCachedEnforcer.AddPolicy(sub, obj, act) +} + +// RemovePolicy 删除策略 +func RemovePolicy(sub, obj, act string) (bool, error) { + return syncedCachedEnforcer.RemovePolicy(sub, obj, act) +} + +// GetPoliciesForUser 获取用户的所有策略 +func GetPoliciesForUser(sub string) [][]string { + policies, _ := syncedCachedEnforcer.GetFilteredPolicy(0, sub) + return policies +} + +// UpdateCasbinApi 更新API权限 +func UpdateCasbinApi(oldPath, newPath, oldMethod, newMethod string) error { + _, err := syncedCachedEnforcer.UpdatePolicy( + []string{"", oldPath, oldMethod}, + []string{"", newPath, newMethod}, + ) + return err +} diff --git a/pkg/jwt/jwt.go b/pkg/jwt/jwt.go new file mode 100644 index 0000000..0678e01 --- /dev/null +++ b/pkg/jwt/jwt.go @@ -0,0 +1,88 @@ +package jwt + +import ( + "errors" + "time" + + "github.com/golang-jwt/jwt/v5" +) + +var ( + ErrTokenExpired = errors.New("token已过期") + ErrTokenNotValidYet = errors.New("token尚未激活") + ErrTokenMalformed = errors.New("token格式错误") + ErrTokenInvalid = errors.New("无效的token") +) + +// CustomClaims 自定义Claims +type CustomClaims struct { + UserID uint `json:"userId"` + Username string `json:"username"` + AuthorityID uint `json:"authorityId"` + BufferTime int64 `json:"bufferTime"` + jwt.RegisteredClaims +} + +// JWT JWT工具 +type JWT struct { + SigningKey []byte + Issuer string + ExpiresAt time.Duration + BufferTime time.Duration +} + +// NewJWT 创建JWT实例 +func NewJWT(signingKey, issuer string, expiresAt, bufferTime time.Duration) *JWT { + return &JWT{ + SigningKey: []byte(signingKey), + Issuer: issuer, + ExpiresAt: expiresAt, + BufferTime: bufferTime, + } +} + +// CreateToken 创建token +func (j *JWT) CreateToken(userID uint, username string, authorityID uint) (string, error) { + claims := CustomClaims{ + UserID: userID, + Username: username, + AuthorityID: authorityID, + BufferTime: int64(j.BufferTime / time.Second), + RegisteredClaims: jwt.RegisteredClaims{ + Issuer: j.Issuer, + ExpiresAt: jwt.NewNumericDate(time.Now().Add(j.ExpiresAt)), + NotBefore: jwt.NewNumericDate(time.Now().Add(-1000)), + IssuedAt: jwt.NewNumericDate(time.Now()), + }, + } + token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) + return token.SignedString(j.SigningKey) +} + +// ParseToken 解析token +func (j *JWT) ParseToken(tokenString string) (*CustomClaims, error) { + token, err := jwt.ParseWithClaims(tokenString, &CustomClaims{}, func(token *jwt.Token) (interface{}, error) { + return j.SigningKey, nil + }) + if err != nil { + switch { + case errors.Is(err, jwt.ErrTokenExpired): + return nil, ErrTokenExpired + case errors.Is(err, jwt.ErrTokenMalformed): + return nil, ErrTokenMalformed + case errors.Is(err, jwt.ErrTokenNotValidYet): + return nil, ErrTokenNotValidYet + default: + return nil, ErrTokenInvalid + } + } + if claims, ok := token.Claims.(*CustomClaims); ok && token.Valid { + return claims, nil + } + return nil, ErrTokenInvalid +} + +// NeedRefresh 判断是否需要刷新token +func (j *JWT) NeedRefresh(claims *CustomClaims) bool { + return claims.ExpiresAt.Time.Sub(time.Now()) < j.BufferTime +} diff --git a/pkg/timer/timer.go b/pkg/timer/timer.go new file mode 100644 index 0000000..930344b --- /dev/null +++ b/pkg/timer/timer.go @@ -0,0 +1,81 @@ +package timer + +import ( + "sync" + + "github.com/robfig/cron/v3" +) + +// Timer 定时任务管理器 +type Timer struct { + cron *cron.Cron + tasks map[string]cron.EntryID + mu sync.RWMutex +} + +// NewTimer 创建定时任务管理器 +func NewTimer() *Timer { + return &Timer{ + cron: cron.New(cron.WithSeconds()), + tasks: make(map[string]cron.EntryID), + } +} + +// Start 启动定时任务 +func (t *Timer) Start() { + t.cron.Start() +} + +// Stop 停止定时任务 +func (t *Timer) Stop() { + t.cron.Stop() +} + +// AddTask 添加定时任务 +func (t *Timer) AddTask(name, spec string, cmd func()) error { + t.mu.Lock() + defer t.mu.Unlock() + + // 如果任务已存在,先删除 + if id, ok := t.tasks[name]; ok { + t.cron.Remove(id) + } + + id, err := t.cron.AddFunc(spec, cmd) + if err != nil { + return err + } + t.tasks[name] = id + return nil +} + +// RemoveTask 删除定时任务 +func (t *Timer) RemoveTask(name string) { + t.mu.Lock() + defer t.mu.Unlock() + + if id, ok := t.tasks[name]; ok { + t.cron.Remove(id) + delete(t.tasks, name) + } +} + +// HasTask 检查任务是否存在 +func (t *Timer) HasTask(name string) bool { + t.mu.RLock() + defer t.mu.RUnlock() + _, ok := t.tasks[name] + return ok +} + +// ListTasks 列出所有任务 +func (t *Timer) ListTasks() []string { + t.mu.RLock() + defer t.mu.RUnlock() + + names := make([]string, 0, len(t.tasks)) + for name := range t.tasks { + names = append(names, name) + } + return names +} diff --git a/pkg/upload/aliyun.go b/pkg/upload/aliyun.go new file mode 100644 index 0000000..ce047c2 --- /dev/null +++ b/pkg/upload/aliyun.go @@ -0,0 +1,79 @@ +package upload + +import ( + "mime/multipart" + "path" + + "github.com/aliyun/aliyun-oss-go-sdk/oss" +) + +// Aliyun 阿里云OSS +type Aliyun struct { + Endpoint string + AccessKeyID string + AccessKeySecret string + BucketName string + BucketURL string + BasePath string +} + +// NewAliyun 创建阿里云OSS +func NewAliyun(endpoint, accessKeyID, accessKeySecret, bucketName, bucketURL, basePath string) *Aliyun { + return &Aliyun{ + Endpoint: endpoint, + AccessKeyID: accessKeyID, + AccessKeySecret: accessKeySecret, + BucketName: bucketName, + BucketURL: bucketURL, + BasePath: basePath, + } +} + +// Upload 上传文件 +func (a *Aliyun) Upload(file *multipart.FileHeader) (string, string, error) { + client, err := oss.New(a.Endpoint, a.AccessKeyID, a.AccessKeySecret) + if err != nil { + return "", "", err + } + + bucket, err := client.Bucket(a.BucketName) + if err != nil { + return "", "", err + } + + // 生成文件名和路径 + fileName := GenerateFileName(file.Filename) + filePath := GeneratePath(a.BasePath) + key := path.Join(filePath, fileName) + + // 打开文件 + src, err := file.Open() + if err != nil { + return "", "", err + } + defer src.Close() + + // 上传 + if err = bucket.PutObject(key, src); err != nil { + return "", "", err + } + + // 返回访问URL和key + accessURL := a.BucketURL + "/" + key + return accessURL, key, nil +} + +// Delete 删除文件 +func (a *Aliyun) Delete(key string) error { + client, err := oss.New(a.Endpoint, a.AccessKeyID, a.AccessKeySecret) + if err != nil { + return err + } + + bucket, err := client.Bucket(a.BucketName) + if err != nil { + return err + } + + return bucket.DeleteObject(key) +} diff --git a/pkg/upload/aws.go b/pkg/upload/aws.go new file mode 100644 index 0000000..037f36b --- /dev/null +++ b/pkg/upload/aws.go @@ -0,0 +1,109 @@ +package upload + +import ( + "context" + "mime/multipart" + "path" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/config" + "github.com/aws/aws-sdk-go-v2/credentials" + "github.com/aws/aws-sdk-go-v2/service/s3" +) + +// AwsS3 AWS S3存储 +type AwsS3 struct { + Bucket string + Region string + Endpoint string + SecretID string + SecretKey string + BaseURL string + PathPrefix string + S3ForcePathStyle bool + DisableSSL bool +} + +// NewAwsS3 创建AWS S3 +func NewAwsS3(bucket, region, endpoint, secretID, secretKey, baseURL, pathPrefix string, s3ForcePathStyle, disableSSL bool) *AwsS3 { + return &AwsS3{ + Bucket: bucket, + Region: region, + Endpoint: endpoint, + SecretID: secretID, + SecretKey: secretKey, + BaseURL: baseURL, + PathPrefix: pathPrefix, + S3ForcePathStyle: s3ForcePathStyle, + DisableSSL: disableSSL, + } +} + +func (a *AwsS3) getClient(ctx context.Context) (*s3.Client, error) { + cfg, err := config.LoadDefaultConfig(ctx, + config.WithRegion(a.Region), + config.WithCredentialsProvider(credentials.NewStaticCredentialsProvider(a.SecretID, a.SecretKey, "")), + ) + if err != nil { + return nil, err + } + + client := s3.NewFromConfig(cfg, func(o *s3.Options) { + if a.Endpoint != "" { + o.BaseEndpoint = aws.String(a.Endpoint) + } + o.UsePathStyle = a.S3ForcePathStyle + }) + return client, nil +} + +// Upload 上传文件 +func (a *AwsS3) Upload(file *multipart.FileHeader) (string, string, error) { + ctx := context.Background() + client, err := a.getClient(ctx) + if err != nil { + return "", "", err + } + + // 生成文件名和路径 + fileName := GenerateFileName(file.Filename) + filePath := GeneratePath(a.PathPrefix) + key := path.Join(filePath, fileName) + + // 打开文件 + src, err := file.Open() + if err != nil { + return "", "", err + } + defer src.Close() + + // 上传 + contentType := file.Header.Get("Content-Type") + _, err = client.PutObject(ctx, &s3.PutObjectInput{ + Bucket: aws.String(a.Bucket), + Key: aws.String(key), + Body: src, + ContentType: aws.String(contentType), + }) + if err != nil { + return "", "", err + } + + // 返回访问URL和key + accessURL := a.BaseURL + "/" + key + return accessURL, key, nil +} + +// Delete 删除文件 +func (a *AwsS3) Delete(key string) error { + ctx := context.Background() + client, err := a.getClient(ctx) + if err != nil { + return err + } + _, err = client.DeleteObject(ctx, &s3.DeleteObjectInput{ + Bucket: aws.String(a.Bucket), + Key: aws.String(key), + }) + return err +} diff --git a/pkg/upload/cloudflare.go b/pkg/upload/cloudflare.go new file mode 100644 index 0000000..bae4613 --- /dev/null +++ b/pkg/upload/cloudflare.go @@ -0,0 +1,103 @@ +package upload + +import ( + "context" + "fmt" + "mime/multipart" + "path" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/config" + "github.com/aws/aws-sdk-go-v2/credentials" + "github.com/aws/aws-sdk-go-v2/service/s3" +) + +// CloudflareR2 Cloudflare R2存储 +type CloudflareR2 struct { + Bucket string + BaseURL string + Path string + AccountID string + AccessKeyID string + SecretAccessKey string +} + +// NewCloudflareR2 创建Cloudflare R2 +func NewCloudflareR2(bucket, baseURL, r2Path, accountID, accessKeyID, secretAccessKey string) *CloudflareR2 { + return &CloudflareR2{ + Bucket: bucket, + BaseURL: baseURL, + Path: r2Path, + AccountID: accountID, + AccessKeyID: accessKeyID, + SecretAccessKey: secretAccessKey, + } +} + +func (c *CloudflareR2) getClient(ctx context.Context) (*s3.Client, error) { + endpoint := fmt.Sprintf("https://%s.r2.cloudflarestorage.com", c.AccountID) + + cfg, err := config.LoadDefaultConfig(ctx, + config.WithCredentialsProvider(credentials.NewStaticCredentialsProvider(c.AccessKeyID, c.SecretAccessKey, "")), + config.WithRegion("auto"), + ) + if err != nil { + return nil, err + } + + client := s3.NewFromConfig(cfg, func(o *s3.Options) { + o.BaseEndpoint = aws.String(endpoint) + }) + return client, nil +} + +// Upload 上传文件 +func (c *CloudflareR2) Upload(file *multipart.FileHeader) (string, string, error) { + ctx := context.Background() + client, err := c.getClient(ctx) + if err != nil { + return "", "", err + } + + // 生成文件名和路径 + fileName := GenerateFileName(file.Filename) + filePath := GeneratePath(c.Path) + key := path.Join(filePath, fileName) + + // 打开文件 + src, err := file.Open() + if err != nil { + return "", "", err + } + defer src.Close() + + // 上传 + contentType := file.Header.Get("Content-Type") + _, err = client.PutObject(ctx, &s3.PutObjectInput{ + Bucket: aws.String(c.Bucket), + Key: aws.String(key), + Body: src, + ContentType: aws.String(contentType), + }) + if err != nil { + return "", "", err + } + + // 返回访问URL和key + accessURL := c.BaseURL + "/" + key + return accessURL, key, nil +} + +// Delete 删除文件 +func (c *CloudflareR2) Delete(key string) error { + ctx := context.Background() + client, err := c.getClient(ctx) + if err != nil { + return err + } + _, err = client.DeleteObject(ctx, &s3.DeleteObjectInput{ + Bucket: aws.String(c.Bucket), + Key: aws.String(key), + }) + return err +} diff --git a/pkg/upload/huawei.go b/pkg/upload/huawei.go new file mode 100644 index 0000000..8774099 --- /dev/null +++ b/pkg/upload/huawei.go @@ -0,0 +1,82 @@ +package upload + +import ( + "mime/multipart" + "path" + + "github.com/huaweicloud/huaweicloud-sdk-go-obs/obs" +) + +// HuaweiObs 华为云OBS +type HuaweiObs struct { + Path string + Bucket string + Endpoint string + AccessKey string + SecretKey string +} + +// NewHuaweiObs 创建华为云OBS +func NewHuaweiObs(obsPath, bucket, endpoint, accessKey, secretKey string) *HuaweiObs { + return &HuaweiObs{ + Path: obsPath, + Bucket: bucket, + Endpoint: endpoint, + AccessKey: accessKey, + SecretKey: secretKey, + } +} + +func (h *HuaweiObs) getClient() (*obs.ObsClient, error) { + return obs.New(h.AccessKey, h.SecretKey, h.Endpoint) +} + +// Upload 上传文件 +func (h *HuaweiObs) Upload(file *multipart.FileHeader) (string, string, error) { + client, err := h.getClient() + if err != nil { + return "", "", err + } + defer client.Close() + + // 生成文件名和路径 + fileName := GenerateFileName(file.Filename) + filePath := GeneratePath(h.Path) + key := path.Join(filePath, fileName) + + // 打开文件 + src, err := file.Open() + if err != nil { + return "", "", err + } + defer src.Close() + + // 上传 + input := &obs.PutObjectInput{} + input.Bucket = h.Bucket + input.Key = key + input.Body = src + _, err = client.PutObject(input) + if err != nil { + return "", "", err + } + + // 返回访问URL和key + accessURL := "https://" + h.Bucket + "." + h.Endpoint + "/" + key + return accessURL, key, nil +} + +// Delete 删除文件 +func (h *HuaweiObs) Delete(key string) error { + client, err := h.getClient() + if err != nil { + return err + } + defer client.Close() + + input := &obs.DeleteObjectInput{} + input.Bucket = h.Bucket + input.Key = key + _, err = client.DeleteObject(input) + return err +} diff --git a/pkg/upload/local.go b/pkg/upload/local.go new file mode 100644 index 0000000..973f515 --- /dev/null +++ b/pkg/upload/local.go @@ -0,0 +1,66 @@ +package upload + +import ( + "io" + "mime/multipart" + "os" + "path" +) + +// Local 本地存储 +type Local struct { + StorePath string + BasePath string +} + +// NewLocal 创建本地存储 +func NewLocal(storePath, basePath string) *Local { + return &Local{ + StorePath: storePath, + BasePath: basePath, + } +} + +// Upload 上传文件 +func (l *Local) Upload(file *multipart.FileHeader) (string, string, error) { + // 生成文件名和路径 + fileName := GenerateFileName(file.Filename) + filePath := GeneratePath(l.BasePath) + fullPath := path.Join(l.StorePath, filePath) + + // 创建目录 + if err := os.MkdirAll(fullPath, os.ModePerm); err != nil { + return "", "", err + } + + // 打开源文件 + src, err := file.Open() + if err != nil { + return "", "", err + } + defer src.Close() + + // 创建目标文件 + dstPath := path.Join(fullPath, fileName) + dst, err := os.Create(dstPath) + if err != nil { + return "", "", err + } + defer dst.Close() + + // 复制文件 + if _, err = io.Copy(dst, src); err != nil { + return "", "", err + } + + // 返回访问路径和存储key + accessPath := path.Join("/", filePath, fileName) + key := path.Join(filePath, fileName) + return accessPath, key, nil +} + +// Delete 删除文件 +func (l *Local) Delete(key string) error { + fullPath := path.Join(l.StorePath, key) + return os.Remove(fullPath) +} diff --git a/pkg/upload/minio.go b/pkg/upload/minio.go new file mode 100644 index 0000000..aa95705 --- /dev/null +++ b/pkg/upload/minio.go @@ -0,0 +1,84 @@ +package upload + +import ( + "context" + "mime/multipart" + "path" + + "github.com/minio/minio-go/v7" + "github.com/minio/minio-go/v7/pkg/credentials" +) + +// Minio MinIO存储 +type Minio struct { + ID string + Secret string + Bucket string + Endpoint string + BasePath string + UseSSL bool +} + +// NewMinio 创建MinIO +func NewMinio(id, secret, bucket, endpoint, basePath string, useSSL bool) *Minio { + return &Minio{ + ID: id, + Secret: secret, + Bucket: bucket, + Endpoint: endpoint, + BasePath: basePath, + UseSSL: useSSL, + } +} + +func (m *Minio) getClient() (*minio.Client, error) { + return minio.New(m.Endpoint, &minio.Options{ + Creds: credentials.NewStaticV4(m.ID, m.Secret, ""), + Secure: m.UseSSL, + }) +} + +// Upload 上传文件 +func (m *Minio) Upload(file *multipart.FileHeader) (string, string, error) { + client, err := m.getClient() + if err != nil { + return "", "", err + } + + // 生成文件名和路径 + fileName := GenerateFileName(file.Filename) + filePath := GeneratePath(m.BasePath) + key := path.Join(filePath, fileName) + + // 打开文件 + src, err := file.Open() + if err != nil { + return "", "", err + } + defer src.Close() + + // 上传 + _, err = client.PutObject(context.Background(), m.Bucket, key, src, file.Size, minio.PutObjectOptions{ + ContentType: file.Header.Get("Content-Type"), + }) + if err != nil { + return "", "", err + } + + // 返回访问URL和key + protocol := "http" + if m.UseSSL { + protocol = "https" + } + accessURL := protocol + "://" + m.Endpoint + "/" + m.Bucket + "/" + key + return accessURL, key, nil +} + +// Delete 删除文件 +func (m *Minio) Delete(key string) error { + client, err := m.getClient() + if err != nil { + return err + } + return client.RemoveObject(context.Background(), m.Bucket, key, minio.RemoveObjectOptions{}) +} diff --git a/pkg/upload/qiniu.go b/pkg/upload/qiniu.go new file mode 100644 index 0000000..9a94446 --- /dev/null +++ b/pkg/upload/qiniu.go @@ -0,0 +1,96 @@ +package upload + +import ( + "context" + "mime/multipart" + "path" + + "github.com/qiniu/go-sdk/v7/auth/qbox" + "github.com/qiniu/go-sdk/v7/storage" +) + +// Qiniu 七牛云 +type Qiniu struct { + Zone string + Bucket string + ImgPath string + AccessKey string + SecretKey string + UseHTTPS bool + UseCdnDomains bool +} + +// NewQiniu 创建七牛云 +func NewQiniu(zone, bucket, imgPath, accessKey, secretKey string, useHTTPS, useCdnDomains bool) *Qiniu { + return &Qiniu{ + Zone: zone, + Bucket: bucket, + ImgPath: imgPath, + AccessKey: accessKey, + SecretKey: secretKey, + UseHTTPS: useHTTPS, + UseCdnDomains: useCdnDomains, + } +} + +func (q *Qiniu) getZone() *storage.Region { + switch q.Zone { + case "ZoneHuadong": + return &storage.ZoneHuadong + case "ZoneHuabei": + return &storage.ZoneHuabei + case "ZoneHuanan": + return &storage.ZoneHuanan + case "ZoneBeimei": + return &storage.ZoneBeimei + case "ZoneXinjiapo": + return &storage.ZoneXinjiapo + default: + return &storage.ZoneHuadong + } +} + +// Upload 上传文件 +func (q *Qiniu) Upload(file *multipart.FileHeader) (string, string, error) { + mac := qbox.NewMac(q.AccessKey, q.SecretKey) + putPolicy := storage.PutPolicy{Scope: q.Bucket} + upToken := putPolicy.UploadToken(mac) + + cfg := storage.Config{ + Zone: q.getZone(), + UseHTTPS: q.UseHTTPS, + UseCdnDomains: q.UseCdnDomains, + } + formUploader := storage.NewFormUploader(&cfg) + + // 生成文件名和路径 + fileName := GenerateFileName(file.Filename) + filePath := GeneratePath("") + key := path.Join(filePath, fileName) + + // 打开文件 + src, err := file.Open() + if err != nil { + return "", "", err + } + defer src.Close() + + // 上传 + ret := storage.PutRet{} + err = formUploader.Put(context.Background(), &ret, upToken, key, src, file.Size, nil) + if err != nil { + return "", "", err + } + + // 返回访问URL和key + accessURL := q.ImgPath + "/" + key + return accessURL, key, nil +} + +// Delete 删除文件 +func (q *Qiniu) Delete(key string) error { + mac := qbox.NewMac(q.AccessKey, q.SecretKey) + cfg := storage.Config{Zone: q.getZone()} + bucketManager := storage.NewBucketManager(mac, &cfg) + return bucketManager.Delete(q.Bucket, key) +} diff --git a/pkg/upload/tencent.go b/pkg/upload/tencent.go new file mode 100644 index 0000000..0001d85 --- /dev/null +++ b/pkg/upload/tencent.go @@ -0,0 +1,79 @@ +package upload + +import ( + "context" + "fmt" + "mime/multipart" + "net/http" + "net/url" + "path" + + "github.com/tencentyun/cos-go-sdk-v5" +) + +// Tencent 腾讯云COS +type Tencent struct { + Bucket string + Region string + SecretID string + SecretKey string + BaseURL string + PathPrefix string +} + +// NewTencent 创建腾讯云COS +func NewTencent(bucket, region, secretID, secretKey, baseURL, pathPrefix string) *Tencent { + return &Tencent{ + Bucket: bucket, + Region: region, + SecretID: secretID, + SecretKey: secretKey, + BaseURL: baseURL, + PathPrefix: pathPrefix, + } +} + +func (t *Tencent) getClient() *cos.Client { + u, _ := url.Parse(fmt.Sprintf("https://%s.cos.%s.myqcloud.com", t.Bucket, t.Region)) + b := &cos.BaseURL{BucketURL: u} + return cos.NewClient(b, &http.Client{ + Transport: &cos.AuthorizationTransport{ + SecretID: t.SecretID, + SecretKey: t.SecretKey, + }, + }) +} + +// Upload 上传文件 +func (t *Tencent) Upload(file *multipart.FileHeader) (string, string, error) { + client := t.getClient() + + // 生成文件名和路径 + fileName := GenerateFileName(file.Filename) + filePath := GeneratePath(t.PathPrefix) + key := path.Join(filePath, fileName) + + // 打开文件 + src, err := file.Open() + if err != nil { + return "", "", err + } + defer src.Close() + + // 上传 + _, err = client.Object.Put(context.Background(), key, src, nil) + if err != nil { + return "", "", err + } + + // 返回访问URL和key + accessURL := t.BaseURL + "/" + key + return accessURL, key, nil +} + +// Delete 删除文件 +func (t *Tencent) Delete(key string) error { + client := t.getClient() + _, err := client.Object.Delete(context.Background(), key) + return err +} diff --git a/pkg/upload/upload.go b/pkg/upload/upload.go new file mode 100644 index 0000000..9bd95a1 --- /dev/null +++ b/pkg/upload/upload.go @@ -0,0 +1,71 @@ +package upload + +import ( + "errors" + "mime/multipart" + "path" + "strings" + "time" + + "github.com/google/uuid" +) + +var ( + ErrFileEmpty = errors.New("文件为空") + ErrFileTooLarge = errors.New("文件过大") + ErrFileTypeError = errors.New("文件类型不允许") +) + +// OSS 对象存储接口 +type OSS interface { + Upload(file *multipart.FileHeader) (string, string, error) + Delete(key string) error +} + +// Config 上传配置 +type Config struct { + Type string // local, aliyun, tencent, qiniu, minio, aws-s3, huawei-obs, cloudflare-r2 + Path string + MaxSize int64 +} + +// GenerateFileName 生成文件名 +func GenerateFileName(originalName string) string { + ext := path.Ext(originalName) + name := uuid.New().String() + return name + ext +} + +// GeneratePath 生成存储路径 +func GeneratePath(basePath string) string { + now := time.Now() + return path.Join(basePath, now.Format("2006/01/02")) +} + +// CheckFileSize 检查文件大小 +func CheckFileSize(size int64, maxSize int64) error { + if size > maxSize { + return ErrFileTooLarge + } + return nil +} + +// CheckFileType 检查文件类型 +func CheckFileType(filename string, allowTypes []string) error { + ext := strings.ToLower(path.Ext(filename)) + for _, t := range allowTypes { + if ext == t || t == "*" { + return nil + } + } + return ErrFileTypeError +} + +// DefaultAllowTypes 默认允许的文件类型 +var DefaultAllowTypes = []string{ + ".jpg", ".jpeg", ".png", ".gif", ".bmp", ".webp", + ".pdf", ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", + ".txt", ".md", ".json", ".xml", ".csv", + ".zip", ".rar", ".7z", ".tar", ".gz", + ".mp3", ".mp4", ".avi", ".mov", ".wmv", +} diff --git a/pkg/utils/breakpoint.go b/pkg/utils/breakpoint.go new file mode 100644 index 0000000..a89dcb2 --- /dev/null +++ b/pkg/utils/breakpoint.go @@ -0,0 +1,91 @@ +package utils + +import ( + "errors" + "os" + "strconv" + "strings" +) + +const ( + breakpointDir = "./breakpointDir/" + finishDir = "./fileDir/" +) + +// BreakPointContinue 断点续传 +// content: 文件片段内容 +// fileName: 文件名 +// contentNumber: 当前片段序号 +// contentTotal: 总片段数 +// fileMd5: 文件MD5 +func BreakPointContinue(content []byte, fileName string, contentNumber int, contentTotal int, fileMd5 string) (string, error) { + path := breakpointDir + fileMd5 + "/" + err := os.MkdirAll(path, os.ModePerm) + if err != nil { + return path, err + } + pathC, err := makeFileContent(content, fileName, path, contentNumber) + return pathC, err +} + +// CheckMd5 检查Md5 +func CheckMd5(content []byte, chunkMd5 string) bool { + fileMd5 := MD5V(content) + return fileMd5 == chunkMd5 +} + +// makeFileContent 创建切片内容 +func makeFileContent(content []byte, fileName string, FileDir string, contentNumber int) (string, error) { + if strings.Contains(fileName, "..") || strings.Contains(FileDir, "..") { + return "", errors.New("文件名或路径不合法") + } + path := FileDir + fileName + "_" + strconv.Itoa(contentNumber) + f, err := os.Create(path) + if err != nil { + return path, err + } + defer f.Close() + _, err = f.Write(content) + if err != nil { + return path, err + } + return path, nil +} + +// MakeFile 合并切片文件 +func MakeFile(fileName string, FileMd5 string) (string, error) { + rd, err := os.ReadDir(breakpointDir + FileMd5) + if err != nil { + return finishDir + fileName, err + } + _ = os.MkdirAll(finishDir, os.ModePerm) + fd, err := os.OpenFile(finishDir+fileName, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0o644) + if err != nil { + return finishDir + fileName, err + } + defer fd.Close() + for k := range rd { + content, _ := os.ReadFile(breakpointDir + FileMd5 + "/" + fileName + "_" + strconv.Itoa(k)) + _, err = fd.Write(content) + if err != nil { + _ = os.Remove(finishDir + fileName) + return finishDir + fileName, err + } + } + return finishDir + fileName, nil +} + +// RemoveChunk 移除切片 +func RemoveChunk(FileMd5 string) error { + return os.RemoveAll(breakpointDir + FileMd5) +} + +// GetBreakpointDir 获取断点续传目录 +func GetBreakpointDir() string { + return breakpointDir +} + +// GetFinishDir 获取完成文件目录 +func GetFinishDir() string { + return finishDir +} diff --git a/pkg/utils/excel.go b/pkg/utils/excel.go new file mode 100644 index 0000000..e6df7d1 --- /dev/null +++ b/pkg/utils/excel.go @@ -0,0 +1,82 @@ +package utils + +import ( + "bytes" + "fmt" + "mime/multipart" + "strconv" + + "github.com/xuri/excelize/v2" +) + +// GetColumnName 获取Excel列名 (1->A, 2->B, ..., 27->AA) +func GetColumnName(n int) string { + columnName := "" + for n > 0 { + n-- + columnName = string(rune('A'+n%26)) + columnName + n /= 26 + } + return columnName +} + +// CreateExcelFile 创建Excel文件 +func CreateExcelFile() *excelize.File { + return excelize.NewFile() +} + +// OpenExcelFile 打开Excel文件 +func OpenExcelFile(file *multipart.FileHeader) (*excelize.File, error) { + src, err := file.Open() + if err != nil { + return nil, err + } + defer src.Close() + return excelize.OpenReader(src) +} + +// WriteExcelRows 写入Excel行数据 +func WriteExcelRows(f *excelize.File, sheetName string, rows [][]interface{}) error { + for i, row := range rows { + for j, cell := range row { + cellName := fmt.Sprintf("%s%d", GetColumnName(j+1), i+1) + if err := f.SetCellValue(sheetName, cellName, cell); err != nil { + return err + } + } + } + return nil +} + +// WriteExcelRow 写入单行数据 +func WriteExcelRow(f *excelize.File, sheetName string, rowIndex int, row []interface{}) error { + for j, cell := range row { + cellName := fmt.Sprintf("%s%d", GetColumnName(j+1), rowIndex) + if err := f.SetCellValue(sheetName, cellName, cell); err != nil { + return err + } + } + return nil +} + +// ExcelToBuffer 将Excel文件写入Buffer +func ExcelToBuffer(f *excelize.File) (*bytes.Buffer, error) { + return f.WriteToBuffer() +} + +// ReadExcelRows 读取Excel所有行 +func ReadExcelRows(f *excelize.File, sheetName string) ([][]string, error) { + return f.GetRows(sheetName) +} + +// SetCellValueAuto 自动类型设置单元格值 +func SetCellValueAuto(f *excelize.File, sheetName, cell string, value string) error { + // 尝试解析为数字 + if v, err := strconv.ParseFloat(value, 64); err == nil { + return f.SetCellValue(sheetName, cell, v) + } + if v, err := strconv.ParseInt(value, 10, 64); err == nil { + return f.SetCellValue(sheetName, cell, v) + } + return f.SetCellValue(sheetName, cell, value) +} diff --git a/pkg/utils/md5.go b/pkg/utils/md5.go new file mode 100644 index 0000000..9d667eb --- /dev/null +++ b/pkg/utils/md5.go @@ -0,0 +1,18 @@ +package utils + +import ( + "crypto/md5" + "encoding/hex" +) + +// MD5V 计算字节数组的MD5值 +func MD5V(data []byte) string { + h := md5.New() + h.Write(data) + return hex.EncodeToString(h.Sum(nil)) +} + +// MD5String 计算字符串的MD5值 +func MD5String(s string) string { + return MD5V([]byte(s)) +} diff --git a/pkg/utils/zip.go b/pkg/utils/zip.go new file mode 100644 index 0000000..7e38dc7 --- /dev/null +++ b/pkg/utils/zip.go @@ -0,0 +1,107 @@ +package utils + +import ( + "archive/zip" + "io" + "os" + "path/filepath" + "strings" +) + +// ZipFiles 压缩文件 +func ZipFiles(filename string, files []string, oldForm, newForm string) error { + newZipFile, err := os.Create(filename) + if err != nil { + return err + } + defer newZipFile.Close() + + zipWriter := zip.NewWriter(newZipFile) + defer zipWriter.Close() + + for _, file := range files { + if err = addFileToZip(zipWriter, file, oldForm, newForm); err != nil { + return err + } + } + return nil +} + +func addFileToZip(zipWriter *zip.Writer, filename, oldForm, newForm string) error { + fileToZip, err := os.Open(filename) + if err != nil { + return err + } + defer fileToZip.Close() + + info, err := fileToZip.Stat() + if err != nil { + return err + } + + header, err := zip.FileInfoHeader(info) + if err != nil { + return err + } + + header.Name = strings.Replace(filename, oldForm, newForm, 1) + header.Method = zip.Deflate + + writer, err := zipWriter.CreateHeader(header) + if err != nil { + return err + } + _, err = io.Copy(writer, fileToZip) + return err +} + +// Unzip 解压文件 +func Unzip(src, dest string) ([]string, error) { + var filenames []string + + r, err := zip.OpenReader(src) + if err != nil { + return filenames, err + } + defer r.Close() + + for _, f := range r.File { + fpath := filepath.Join(dest, f.Name) + + // 安全检查:防止路径遍历攻击 + if !strings.HasPrefix(fpath, filepath.Clean(dest)+string(os.PathSeparator)) { + continue + } + + filenames = append(filenames, fpath) + + if f.FileInfo().IsDir() { + os.MkdirAll(fpath, os.ModePerm) + continue + } + + if err = os.MkdirAll(filepath.Dir(fpath), os.ModePerm); err != nil { + return filenames, err + } + + outFile, err := os.OpenFile(fpath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode()) + if err != nil { + return filenames, err + } + + rc, err := f.Open() + if err != nil { + outFile.Close() + return filenames, err + } + + _, err = io.Copy(outFile, rc) + outFile.Close() + rc.Close() + + if err != nil { + return filenames, err + } + } + return filenames, nil +}