From e3ca223dea6a3e42116c15b463102227a5cd60fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A1=80=E5=B0=BC=E9=BE=9F?= <365252428@qq.com> Date: Sat, 22 Feb 2025 15:10:20 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=96=87=E4=BB=B6=E4=B8=8A?= =?UTF-8?q?=E4=BC=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/config/config.go | 12 +- conf/conf.ini | 11 +- docs/dev/conf.ini | 10 +- go.mod | 16 +- go.sum | 28 ++- pkg/logic/baidu.go | 58 +++++++ pkg/logic/upload.go | 160 +++++++++++++++++ pkg/model/baidu.go | 12 ++ pkg/model/common.go | 23 +++ pkg/router/router.go | 7 + pkg/service/init.go | 2 +- pkg/service/upload/upload.go | 321 +++++++++++++++++++++++++++++++++++ pkg/utils/picture.go | 62 +++++++ pkg/utils/untils.go | 80 +++++++++ 14 files changed, 789 insertions(+), 13 deletions(-) create mode 100644 pkg/logic/baidu.go create mode 100644 pkg/logic/upload.go create mode 100644 pkg/model/baidu.go create mode 100644 pkg/model/common.go create mode 100644 pkg/service/upload/upload.go create mode 100644 pkg/utils/picture.go create mode 100644 pkg/utils/untils.go diff --git a/cmd/config/config.go b/cmd/config/config.go index 40af4a9..f02dec1 100644 --- a/cmd/config/config.go +++ b/cmd/config/config.go @@ -114,7 +114,14 @@ type System struct { Host string RedirectUri string } - +type Oss struct { + AccessKeyId string + AccessKeySecret string + Endpoint string + BucketName string + BaseDir string + CdnHost string +} type Mobile struct { SK string AK string @@ -133,6 +140,7 @@ type Config struct { System System `toml:"system"` Mobile Mobile `toml:"mobile"` Ai Ai `toml:"ai"` + Oss Oss `toml:"oss"` } /********start-配置信息*********/ @@ -171,7 +179,7 @@ func LoadEnvFromFileInfo(data string) (*Config, error) { return AppConfig, nil } -func GetOptions() { +func GetOptions1() { iniConf, err := common.GetConf() if err != nil { panic("iniConf error") diff --git a/conf/conf.ini b/conf/conf.ini index 1185b9a..5c4d8aa 100644 --- a/conf/conf.ini +++ b/conf/conf.ini @@ -8,11 +8,18 @@ RedirectUri = "/api/redirect/url" [bos] Ak = "ALTAKxrqOQHnAN525Tb2GX4Bhe" Sk = "d2ecaa9d75114d3b9f42b99014198306" -BucketName = "dci-file-new" +BucketName = "dci-file-new" BosUrl = ".bj.bcebos.com" BosBaseDir = "fonchain-main" BosHttp = "https://" - +BosDomain = "cdns.fontree.cn" +[oss] +AccessKeyId = "LTAI5tLz1fSK53FQAEC9uNSb" +AccessKeySecret = "oGB9chrQzQzITXR2IGv37Ji5WxZh4j" +Endpoint = "oss-cn-hangzhou.aliyuncs.com" +BucketName = "fontree-test" +BaseDir = "fonchain-main" +CdnHost = "https://cdn-test.szjixun.cn" [redis] RedisDB = "1" RedisAddr = "127.0.0.1:6379" diff --git a/docs/dev/conf.ini b/docs/dev/conf.ini index e4da629..18d154c 100644 --- a/docs/dev/conf.ini +++ b/docs/dev/conf.ini @@ -8,10 +8,18 @@ RedirectUri = "/api/redirect/url" [bos] Ak = "ALTAKxrqOQHnAN525Tb2GX4Bhe" Sk = "d2ecaa9d75114d3b9f42b99014198306" -BucketName = "dci-file-new" +BucketName = "dci-file-new" BosUrl = ".bj.bcebos.com" BosBaseDir = "fonchain-main" BosHttp = "https://" +BosDomain = "cdns.fontree.cn" +[oss] +AccessKeyId = "LTAI5tLz1fSK53FQAEC9uNSb" +AccessKeySecret = "oGB9chrQzQzITXR2IGv37Ji5WxZh4j" +Endpoint = "oss-cn-hangzhou.aliyuncs.com" +BucketName = "fontree-test" +BaseDir = "fonchain-main" +CdnHost = "https://cdn-test.szjixun.cn" [redis] RedisDB = "1" diff --git a/go.mod b/go.mod index 9128b16..b79cde0 100644 --- a/go.mod +++ b/go.mod @@ -34,10 +34,10 @@ require ( //github.com/fonchain_enterprise/utils/logger v0.0.0-00010101000000-000000000000 github.com/gin-contrib/gzip v0.0.5 github.com/gin-gonic/gin v1.9.1 - github.com/golang/protobuf v1.5.2 + github.com/golang/protobuf v1.5.4 github.com/mwitkow/go-proto-validators v0.3.2 github.com/pkg/errors v0.9.1 // indirect - google.golang.org/protobuf v1.31.0 + google.golang.org/protobuf v1.33.0 gopkg.in/ini.v1 v1.67.0 ) @@ -94,7 +94,7 @@ require ( github.com/prometheus/procfs v0.7.3 // indirect github.com/prometheus/statsd_exporter v0.21.0 // indirect github.com/robfig/cron/v3 v3.0.1 // indirect - github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b // indirect + github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b github.com/shirou/gopsutil v3.20.11+incompatible // indirect github.com/uber/jaeger-client-go v2.29.1+incompatible // indirect github.com/uber/jaeger-lib v2.4.1+incompatible // indirect @@ -102,7 +102,7 @@ require ( go.opencensus.io v0.23.0 // indirect go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.6.0 // indirect - go.uber.org/zap v1.21.0 // indirect + go.uber.org/zap v1.21.0 golang.org/x/crypto v0.19.0 // indirect golang.org/x/net v0.21.0 // indirect golang.org/x/sys v0.18.0 // indirect @@ -115,10 +115,15 @@ require ( require ( github.com/BurntSushi/toml v1.2.1 + github.com/disintegration/imaging v1.6.2 + github.com/fonchain_enterprise/utils/objstorage v0.0.0-00010101000000-000000000000 github.com/gin-contrib/pprof v1.4.0 github.com/go-redis/redis v6.15.9+incompatible + github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e github.com/spf13/viper v1.7.1 + github.com/u2takey/ffmpeg-go v0.5.0 + golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8 ) require ( @@ -126,6 +131,8 @@ require ( github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5 // indirect github.com/alibaba/sentinel-golang v1.0.4 // indirect github.com/aliyun/alibaba-cloud-sdk-go v1.61.18 // indirect + github.com/aws/aws-sdk-go v1.38.20 // indirect + github.com/baidubce/bce-sdk-go v0.9.123 // indirect github.com/buger/jsonparser v1.1.1 // indirect github.com/bytedance/sonic v1.9.1 // indirect github.com/census-instrumentation/opencensus-proto v0.2.1 // indirect @@ -176,6 +183,7 @@ require ( github.com/tklauser/go-sysconf v0.3.6 // indirect github.com/tklauser/numcpus v0.2.2 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + github.com/u2takey/go-utils v0.3.1 // indirect github.com/zouyx/agollo/v3 v3.4.5 // indirect go.etcd.io/etcd/api/v3 v3.5.4 // indirect go.etcd.io/etcd/client/pkg/v3 v3.5.4 // indirect diff --git a/go.sum b/go.sum index aa93cc3..cffc5c0 100644 --- a/go.sum +++ b/go.sum @@ -69,6 +69,7 @@ github.com/alibaba/sentinel-golang v1.0.4 h1:i0wtMvNVdy7vM4DdzYrlC4r/Mpk1OKUUBur github.com/alibaba/sentinel-golang v1.0.4/go.mod h1:Lag5rIYyJiPOylK8Kku2P+a23gdKMMqzQS7wTnjWEpk= github.com/aliyun/alibaba-cloud-sdk-go v1.61.18 h1:zOVTBdCKFd9JbCKz9/nt+FovbjPFmb7mUnp8nH9fQBA= github.com/aliyun/alibaba-cloud-sdk-go v1.61.18/go.mod h1:v8ESoHo4SyHmuB4b1tJqDHxfTGEciD+yhvOU/5s1Rfk= +github.com/aliyun/aliyun-oss-go-sdk v2.2.4+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= github.com/aliyun/aliyun-oss-go-sdk v2.2.6+incompatible h1:KXeJoM1wo9I/6xPTyt6qCxoSZnmASiAjlrr0dyTUKt8= github.com/aliyun/aliyun-oss-go-sdk v2.2.6+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= @@ -88,6 +89,8 @@ github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgI github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go v1.38.20 h1:QbzNx/tdfATbdKfubBpkt84OM6oBkxQZRw6+bW2GyeA= +github.com/aws/aws-sdk-go v1.38.20/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/aws/aws-sdk-go-v2 v1.9.2/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4= github.com/aws/aws-sdk-go-v2/config v1.8.3/go.mod h1:4AEiLtAb8kLs7vgw2ZV3p2VZ1+hBavOc84hqxVNpCyw= @@ -99,6 +102,8 @@ github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.3.2/go.mod h1:72H github.com/aws/aws-sdk-go-v2/service/sso v1.4.2/go.mod h1:NBvT9R1MEF+Ud6ApJKM0G+IkPchKS7p7c2YPKwHmBOk= github.com/aws/aws-sdk-go-v2/service/sts v1.7.2/go.mod h1:8EzeIqfWt2wWT4rJVu3f21TfrhJ8AEMzVybRNSb/b4g= github.com/aws/smithy-go v1.8.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E= +github.com/baidubce/bce-sdk-go v0.9.123 h1:3VvDG9o8cNRUmzFfT7OSeYcHEkl+Kg4Bn4SsfAuM+/I= +github.com/baidubce/bce-sdk-go v0.9.123/go.mod h1:zbYJMQwE4IZuyrJiFO8tO8NbtYiKTFTbwh4eIsqjVdg= github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -174,6 +179,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c= +github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4= github.com/dubbogo/go-zookeeper v1.0.3/go.mod h1:fn6n2CAEer3novYgk9ULLwAjuV8/g4DdC2ENwRb6E+c= github.com/dubbogo/go-zookeeper v1.0.4-0.20211212162352-f9d2183d89d5 h1:XoR8SSVziXe698dt4uZYDfsmHpKLemqAgFyndQsq5Kw= github.com/dubbogo/go-zookeeper v1.0.4-0.20211212162352-f9d2183d89d5/go.mod h1:fn6n2CAEer3novYgk9ULLwAjuV8/g4DdC2ENwRb6E+c= @@ -263,6 +270,7 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9 github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0 h1:TrB8swr/68K7m9CcGut2g3UOihhbcbiMAYiuTXdEih4= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -343,8 +351,9 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= @@ -655,6 +664,7 @@ github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJ github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= +github.com/panjf2000/ants/v2 v2.4.2/go.mod h1:f6F0NZVFsGCp5A7QW/Zj/m92atWwOkY0OIhFxRNFr4A= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= @@ -738,6 +748,8 @@ github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTE github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd h1:CmH9+J6ZSsIjUK3dcGsnCnO41eRBOnY12zwkn5qVwgc= +github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= @@ -826,6 +838,10 @@ github.com/toolkits/concurrent v0.0.0-20150624120057-a4371d70e3e3/go.mod h1:QDlp github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= +github.com/u2takey/ffmpeg-go v0.5.0 h1:r7d86XuL7uLWJ5mzSeQ03uvjfIhiJYvsRAJFCW4uklU= +github.com/u2takey/ffmpeg-go v0.5.0/go.mod h1:ruZWkvC1FEiUNjmROowOAps3ZcWxEiOpFoHCvk97kGc= +github.com/u2takey/go-utils v0.3.1 h1:TaQTgmEZZeDHQFYfd+AdUT1cT4QJgJn/XVPELhHw4ys= +github.com/u2takey/go-utils v0.3.1/go.mod h1:6e+v5vEZ/6gu12w/DC2ixZdZtCrNokVxD0JUklcqdCs= github.com/uber/jaeger-client-go v2.29.1+incompatible h1:R9ec3zO3sGpzs0abd43Y+fBZRJ9uiH6lXyR/+u6brW4= github.com/uber/jaeger-client-go v2.29.1+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg= @@ -909,6 +925,7 @@ go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= +gocv.io/x/gocv v0.25.0/go.mod h1:Rar2PS6DV+T4FL+PM535EImD/h13hGVaHhnCu1xarBs= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= @@ -943,6 +960,8 @@ golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8H golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8 h1:hVwzHzIUGRjiF7EcUjqNxk3NCfkPxbDKRdnNE1Rpg0U= +golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1080,6 +1099,7 @@ golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1130,6 +1150,7 @@ golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1304,8 +1325,8 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1335,6 +1356,7 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= diff --git a/pkg/logic/baidu.go b/pkg/logic/baidu.go new file mode 100644 index 0000000..4dec9d0 --- /dev/null +++ b/pkg/logic/baidu.go @@ -0,0 +1,58 @@ +package logic + +import ( + "dubbo.apache.org/dubbo-go/v3/common/logger" + "encoding/json" + "errors" + "fmt" + "fonchain-fiee/pkg/model" + "fonchain-fiee/pkg/utils" + "time" +) + +const ( + grantType = "client_credentials" + clientId = "SjscdLEybzyxiV7lXKA5iSvZ" + clientSecret = "22fCduMdCarO6WWOi4WiSmt9rIeez3FW" +) + +var accessToken string +var expiresIn uint64 + +func GetImageAccessToken() (string, error) { + var ( + resObj model.BaiduAccessToken + err error + // daoAccessToken entity.AccessToken + ) + if expiresIn == 0 || expiresIn < uint64(time.Now().Unix()) { + fmt.Println(1) + if resObj, err = getAccessTokenWithApi(); err != nil { //从链上获取 + return "", err + } + accessToken = resObj.Access_token + expiresIn = resObj.Expires_in + } + + return accessToken, nil + +} + +func getAccessTokenWithApi() (model.BaiduAccessToken, error) { + var ( + resObj model.BaiduAccessToken + err error + ) + url := "https://aip.baidubce.com/oauth/2.0/token" + urlReq := "?grant_type=" + grantType + "&client_id=" + clientId + "&client_secret=" + clientSecret + res := utils.Get(url + urlReq) + if err = json.Unmarshal([]byte(res), &resObj); err != nil { + logger.Error("getAccessTokenWithApi json err", err) + return resObj, err + } + if resObj.Error != "" { + logger.Error("getAccessTokenWithApi err", err) + return resObj, errors.New(resObj.Error_description) + } + return resObj, err +} diff --git a/pkg/logic/upload.go b/pkg/logic/upload.go new file mode 100644 index 0000000..f273b61 --- /dev/null +++ b/pkg/logic/upload.go @@ -0,0 +1,160 @@ +package logic + +import ( + "dubbo.apache.org/dubbo-go/v3/common/logger" + "errors" + "fmt" + "fonchain-fiee/pkg/config" + "fonchain-fiee/pkg/e" + "github.com/fonchain_enterprise/utils/objstorage" + "github.com/rwcarlsen/goexif/exif" + "golang.org/x/image/bmp" + "image" + "image/jpeg" + "image/png" + "io/ioutil" + "os" + "path" + "strings" +) + +type IUpload interface{} + +type Upload struct{} + +// ReadOrientation 方向判断 +func ReadOrientation(filename string) (direct int, err error) { + file, err := os.Open(filename) + defer file.Close() + if err != nil { + logger.Error("failed to open file, err: ", err) + return + } + x, err := exif.Decode(file) + if err != nil { + logger.Error("failed to decode file, err: ", err) + return + } + orientation, err := x.Get(exif.Orientation) + if err != nil { + logger.Error("failed to orientation file, err: ", err) + return + } + direct, err = orientation.Int(0) + if err != nil { + logger.Error("failed to convert type file, err: ", err) + return + } + return +} + +// 旋转90度 +func rotate90(m image.Image) image.Image { + rotate90 := image.NewRGBA(image.Rect(0, 0, m.Bounds().Dy(), m.Bounds().Dx())) + // 矩阵旋转 + for x := m.Bounds().Min.Y; x < m.Bounds().Max.Y; x++ { + for y := m.Bounds().Max.X - 1; y >= m.Bounds().Min.X; y-- { + // 设置像素点 + rotate90.Set(m.Bounds().Max.Y-x, y, m.At(y, x)) + } + } + return rotate90 +} + +// 旋转180度 +func rotate180(m image.Image) image.Image { + rotate180 := image.NewRGBA(image.Rect(0, 0, m.Bounds().Dx(), m.Bounds().Dy())) + // 矩阵旋转 + for x := m.Bounds().Min.X; x < m.Bounds().Max.X; x++ { + for y := m.Bounds().Min.Y; y < m.Bounds().Max.Y; y++ { + // 设置像素点 + rotate180.Set(m.Bounds().Max.X-x, m.Bounds().Max.Y-y, m.At(x, y)) + } + } + return rotate180 +} + +// 旋转270度 +func rotate270(m image.Image) image.Image { + rotate270 := image.NewRGBA(image.Rect(0, 0, m.Bounds().Dy(), m.Bounds().Dx())) + // 矩阵旋转 + for x := m.Bounds().Min.Y; x < m.Bounds().Max.Y; x++ { + for y := m.Bounds().Max.X - 1; y >= m.Bounds().Min.X; y-- { + // 设置像素点 + rotate270.Set(x, m.Bounds().Max.X-y, m.At(y, x)) + } + } + return rotate270 +} + +func MakeThumbnail(imagePath, savePath string) error { + prefix := strings.ToLower(path.Ext("./2.jpg")) + ori, err := ReadOrientation(imagePath) + if err != nil { + return err + } + file, _ := os.Open(imagePath) + defer file.Close() + img, _, err := image.Decode(file) + if err != nil { + return err + } + //苹果手机拍照的图片,会有方向属性Orientation, + //经过Decode和Encode,编码处理后,方向属性会丢失,导致图片被旋转 + switch ori { + case 6: //90度图片旋转 + img = rotate90(img) + case 3: + img = rotate180(img) + case 8: + img = rotate270(img) + } + newImg, _ := os.Create(savePath) + defer newImg.Close() + switch prefix { + case ".jpg", ".jpeg": + err = jpeg.Encode(newImg, img, &jpeg.Options{Quality: 100}) + case "png": + err = png.Encode(newImg, img) + case "bmp": + err = bmp.Encode(newImg, img) + default: + err = jpeg.Encode(newImg, img, &jpeg.Options{Quality: 100}) + } + if err != nil { + logger.Error("Encode err", err) + return err + } + return nil +} + +func (u *Upload) PutBos(filePath string, mediaType string, needRemove bool) (url string, err error) { + BOSClient, err := objstorage.NewOSS(config.ConfigData.Oss.AccessKeyId, config.ConfigData.Oss.AccessKeySecret, config.ConfigData.Oss.Endpoint) + if err != nil { + logger.Errorf("PutBos NewOOS err ", err) + err = errors.New(e.GetMsg(e.ErrorUploadBos)) + return + } + f, err := os.Open(filePath) + if err != nil { + logger.Errorf("PutBos Open err %+v", err.Error()) + return + } + fileBytes, _ := ioutil.ReadAll(f) + f.Close() + //删除本地文件 + if needRemove { + os.Remove(filePath) + } + filePath = strings.Replace(filePath, "./runtime", "", 1) + var objectName string = fmt.Sprintf("%s/%s%s", config.ConfigData.Oss.BaseDir, config.Env, filePath) + _, err = BOSClient.PutObjectFromBytes(config.ConfigData.Oss.BucketName, objectName, fileBytes) + if err != nil { + logger.Errorf("PutBos PutObject err %+v", err.Error()) + err = errors.New(e.GetMsg(e.ErrorUploadBos)) + return + } + //url = fmt.Sprintf("%s%s%s/%s", config.BosHttp, config.BosBucketName, config.BosUrl, objectName) + url = fmt.Sprintf("%s/%s", config.ConfigData.Oss.CdnHost, objectName) + return +} diff --git a/pkg/model/baidu.go b/pkg/model/baidu.go new file mode 100644 index 0000000..1d0c1a9 --- /dev/null +++ b/pkg/model/baidu.go @@ -0,0 +1,12 @@ +package model + +type BaiduAccessToken struct { + Refresh_token string `json:"refresh_token"` + Expires_in uint64 `json:"expires_in"` + Scope string `json:"scope"` + Session_key string `json:"session_key"` + Access_token string `json:"access_token"` + Session_secret string `json:"session_secret"` + Error string `json:"error"` + Error_description string `json:"error_description"` +} diff --git a/pkg/model/common.go b/pkg/model/common.go new file mode 100644 index 0000000..54efde5 --- /dev/null +++ b/pkg/model/common.go @@ -0,0 +1,23 @@ +package model + +const ( + HttpType = "http://" + HttpsType = "https://" + TmpArtworkDir = "./runtime/tmp/artworks" + TmpArtistDir = "./runtime/tmp/artists" + MediaPath = "./runtime/" + TplPath = "./data/" + ImgActionRotate = "rotate" //旋转 + MediaTypeVideo = "video" + MediaTypeImage = "video" +) + +const ( + DateTimeFormat = "2006-01-02 15:04:05" + DateFormat = "2006-01-02" +) + +type RespSendIndexes struct { + Code int `json:"code"` + Msg string `json:"msg"` +} diff --git a/pkg/router/router.go b/pkg/router/router.go index 36064ea..ac1fa84 100644 --- a/pkg/router/router.go +++ b/pkg/router/router.go @@ -8,6 +8,7 @@ import ( "fonchain-fiee/pkg/service/lang" "fonchain-fiee/pkg/service/qr" "fonchain-fiee/pkg/service/redirect" + "fonchain-fiee/pkg/service/upload" "fonchain-fiee/pkg/service/version" "github.com/gin-contrib/gzip" "net/http" @@ -59,6 +60,12 @@ func NewRouter() *gin.Engine { acRoute.POST("approval", account.UserApproval) //实名审核 } } + // 上传 + upData := privateGroup.Group("upload") + upData.Use(middleware.CheckLogin(service.AccountProvider)) + { + upData.POST("img", upload.UploadImg) + } { //图片相关 imageRoute := v1.Group("image") diff --git a/pkg/service/init.go b/pkg/service/init.go index a9564fd..36f5188 100644 --- a/pkg/service/init.go +++ b/pkg/service/init.go @@ -7,7 +7,7 @@ import ( "fmt" "fonchain-fiee/api/account" "fonchain-fiee/api/bundle" - pkConfig "fonchain-fiee/cmd/config" + pkConfig "fonchain-fiee/pkg/config" "os" ) diff --git a/pkg/service/upload/upload.go b/pkg/service/upload/upload.go new file mode 100644 index 0000000..7289d18 --- /dev/null +++ b/pkg/service/upload/upload.go @@ -0,0 +1,321 @@ +package upload + +import ( + "bytes" + "encoding/base64" + "encoding/json" + "errors" + "fmt" + "fonchain-fiee/pkg/config" + "fonchain-fiee/pkg/e" + "fonchain-fiee/pkg/logic" + "fonchain-fiee/pkg/model" + "fonchain-fiee/pkg/service" + "fonchain-fiee/pkg/utils" + "github.com/disintegration/imaging" + "github.com/fonchain_enterprise/utils/objstorage" + "github.com/gin-gonic/gin" + uuid "github.com/satori/go.uuid" + "io" + + ffmpeg "github.com/u2takey/ffmpeg-go" + "go.uber.org/zap" + "io/ioutil" + "mime/multipart" + "net/url" + "os" + "path" + "path/filepath" + "strconv" + "strings" +) + +const ( + MediaPath = "./runtime/" + RouteType = "static/" + VideoType = "video" + ImageType = "image" + PngType = "png" + ArtworkFilePath = "artwork" + ArtworkChunkBasePath = "./runtime/tmp/artworks" +) + +func UploadImg(c *gin.Context) { + var err error + var filename string + var fileFullName string + source := c.PostForm("source") + mask := c.PostForm("mask") + action := c.PostForm("action") + defineFileName := c.PostForm("defineFileName") + urlParam := c.PostForm("urlParam") + if mask == "" { + mask = "default" + } + mediaType := c.PostForm("type") + zap.L().Info("UploadImg 1", zap.Any("mask", mask)) + var BasePath string + if mediaType == "" || mediaType == ImageType { + mediaType = ImageType + } + BasePath = fmt.Sprintf("%s%s", MediaPath, mediaType) + //BaseRoute = fmt.Sprintf("%s%s", RouteType, mediaType) + var isCompress int + if cStr, ok := c.GetPostForm("is_compress"); ok { + var errS error + isCompress, errS = strconv.Atoi(cStr) + if errS != nil { + service.Error(c, err) + return + } + } + zap.L().Info("UploadImg 2 ", zap.Any("mask", mask)) + // 检验参数 + if mask == "" || source == "" { + service.Error(c, err) + return + } + file, err := c.FormFile("file") + // 检验文件 + if err != nil { + zap.L().Error("Upload FormFile err", zap.Error(err)) + service.Error(c, err) + return + } + //logger.Errorf("UploadImg 3 %+v", mask) + // 判断是不是视频或者需要压缩 + var oriUrl string + if isCompress != 1 && mediaType != "video" && action == "" { + oriUrl, err = quickBos(file, mediaType, mask, source, defineFileName) + if err != nil { + service.Error(c, err) + return + } + if urlParam != "" { + oriUrl = fmt.Sprintf("%s?%s", oriUrl, urlParam) + } + service.Success(c, oriUrl) + return + } + //创建文件名 + fileExt := strings.ToLower(path.Ext(file.Filename)) + if defineFileName != "" { + fileFullName = defineFileName + } else { + newUu, _err := uuid.NewV4() + if _err != nil { + service.Error(c, err) + return + } + filename = newUu.String() + fileFullName = fmt.Sprintf("%s%s", filename, fileExt) + } + //检测文件夹 不存在就创建 + imgPath := fmt.Sprintf("%s/%s/%s", BasePath, source, mask) + _, err = utils.CheckDirPath(imgPath, true) + if err != nil { + service.Error(c, err) + return + } + dst := fmt.Sprintf("%s/%s", imgPath, fileFullName) + // 保存文件至指定路径 + err = c.SaveUploadedFile(file, dst) + if err != nil { + service.Error(c, err) + return + } + if action == model.ImgActionRotate { + fileFullName = fmt.Sprintf("%s%s", filename, fileExt) + newDst := fmt.Sprintf("%s/%s_rotate%v", imgPath, filename, fileExt) + if err = logic.MakeThumbnail(dst, newDst); err != nil { + //ResponseQuickMsg(c, e.Failed, e.GetMsg(e.ERROR_ROTATE_IMG), nil) + //return + } else { + _ = os.Remove(dst) + dst = newDst + } + } + //localUrl := fmt.Sprintf("%s/%s/%s/%s/%s", config.ServerDM, BaseRoute, source, mask, fileFullName) + var data map[string]string = make(map[string]string, 2) + //data["ori_url"] = localUrl + + if int32(isCompress) == 1 { + //压缩图片并存储在原图路径,命名格式xx.jpg_small.jpg + fileFullName = fmt.Sprintf("%s_small%s", filename, fileExt) + newDst := fmt.Sprintf("%s/%s", imgPath, fileFullName) + //compressUrl := fmt.Sprintf("%s/%s/%s/%s/%s", config.ServerDM, BaseRoute, source, mask, fileFullName) + err = utils.CompressJPG(dst, newDst) + compressUrl, err := PutBos(newDst, mediaType, true) + if err != nil { + service.Error(c, err) + return + } + data["compress_url"] = compressUrl + } + // 如果是视频需要截图图片做封面 + if mediaType == VideoType { + videoCover := fmt.Sprintf("%s/%s", imgPath, filename) + _, err = GetSnapshot(dst, videoCover, 1) + if err != nil { + zap.L().Error("GetSnapshot err", zap.Error(err)) + service.Error(c, err) + return + } + zap.L().Info("UploadImg 8.1 videoCover", zap.Any("videoCover", videoCover)) + //data["cover_url"] = fmt.Sprintf("%s/%s/%s/%s/%s", config.ServerDM, BaseRoute, source, mask, fmt.Sprintf("%s.%s", filename, PngType)) + coverUrl, err := PutBos(videoCover+"."+PngType, mediaType, true) + if urlParam != "" { + coverUrl = fmt.Sprintf("%s?%s", coverUrl, urlParam) + } + data["cover_url"] = coverUrl + if err != nil { + zap.L().Error("Upload GetSnapshot err", zap.Error(err)) + service.Error(c, err) + return + } + //ResponseQuickMsg(c, e.Ok, e.GetMsg(e.SUCCESS), data) + //return + } + ossUrl, err := PutBos(dst, mediaType, true) + if err != nil { + service.Error(c, err) + return + } + if urlParam != "" { + ossUrl = fmt.Sprintf("%s?%s", ossUrl, urlParam) + } + data["ori_url"] = ossUrl + service.Success(c, data) + return +} +func quickBos(file *multipart.FileHeader, mediaType string, mask string, source string, defineFileName string) (url string, err error) { + newFile, _ := file.Open() + var filename string + defer newFile.Close() + if defineFileName != "" { + filename = defineFileName + } else { + uuids, _ := uuid.NewV4() + filename = uuids.String() + filename = fmt.Sprintf("%s%s", filename, filepath.Ext(file.Filename)) + } + filePath := fmt.Sprintf("%s/%s/%s/%s", mediaType, mask, source, filename) + fileBytes, _ := ioutil.ReadAll(newFile) + if mediaType == "image" { + if err = BaiduCheckImage(fileBytes); err != nil { + return + } + } + var objectName string = fmt.Sprintf("%s/%s/%s", config.ConfigData.Oss.BaseDir, config.Env, filePath) + BOSClient, _ := objstorage.NewOSS(config.ConfigData.Oss.AccessKeyId, config.ConfigData.Oss.AccessKeySecret, config.ConfigData.Oss.Endpoint) + _, err = BOSClient.PutObjectFromBytes(config.ConfigData.Oss.BucketName, objectName, fileBytes) + if err != nil { + //logger.Errorf("quickOss err", err) + return + } + //url = fmt.Sprintf("%s%s%s/%s", config.BosHttp, config.BosBucketName, config.BosUrl, objectName) + url = fmt.Sprintf("%s/%s", config.ConfigData.Oss.CdnHost, objectName) + return +} + +// BaiduCheckImage 图片鉴黄 +func BaiduCheckImage(imageByte []byte) (err error) { + return + var ( + accesstoken string + response string + ) + sourcestring := base64.StdEncoding.EncodeToString(imageByte) + if accesstoken, err = logic.GetImageAccessToken(); err != nil { + return err + } + host := "https://aip.baidubce.com/rest/2.0/solution/v1/img_censor/v2/user_defined?access_token=[" + accesstoken + "]" + if response, err = utils.PostForm(host, url.Values{"image": {sourcestring}}); err != nil { + //logger.Error("user_defined PostForm err", err) + return err + } + var res struct { + ErrorCode int64 `json:"error_code"` + ErrorMsg string `json:"error_msg"` + Conclusion string `json:"conclusion"` + Log_id uint64 `json:"log_id"` + IsHitMd5 bool `json:"isHitMd5"` + ConclusionType int64 `json:"conclusionType"` + } + if err = json.Unmarshal([]byte(response), &res); err != nil { + //err = errors.New(e.GetMsg(e.JsonUnmarshal)) + return + } + //logger.Error("user_defined res", res) + if res.ErrorCode != 0 || res.ErrorMsg != "" { + return errors.New(e.GetMsg(e.ERROR_BAIDU_FAIL)) + } + if res.Conclusion != "合规" && res.Conclusion != "疑似" { + return errors.New(e.GetMsg(e.ERROR_BAIDU_IMAGE)) + } + return nil +} +func PutBos(filePath string, mediaType string, needRemove bool) (url string, err error) { + BOSClient, err := objstorage.NewOSS(config.ConfigData.Oss.AccessKeyId, config.ConfigData.Oss.AccessKeySecret, config.ConfigData.Oss.Endpoint) + if err != nil { + //logger.Errorf("PutBos NewOss err ", err) + err = errors.New(e.GetMsg(e.ErrorUploadBos)) + return + } + f, err := os.Open(filePath) + if err != nil { + //logger.Errorf("PutBos Open err %+v", err.Error()) + return + } + fileBytes, _ := io.ReadAll(f) + f.Close() + //删除本地文件 + if needRemove { + os.Remove(filePath) + } + if mediaType == "image" { + if err = BaiduCheckImage(fileBytes); err != nil { + return + } + } + filePath = strings.Replace(filePath, "./runtime", "", 1) + var objectName string = fmt.Sprintf("%s/%s%s", config.ConfigData.Oss.BaseDir, config.Env, filePath) + _, err = BOSClient.PutObjectFromBytes(config.ConfigData.Oss.BucketName, objectName, fileBytes) + if err != nil { + //logger.Errorf("PutBos PutObject err %+v", err.Error()) + err = errors.New(e.GetMsg(e.ErrorUploadBos)) + return + } + //url = fmt.Sprintf("%s%s%s/%s", config.BosHttp, config.BosBucketName, config.BosUrl, objectName) + url = fmt.Sprintf("%s/%s", config.ConfigData.Oss.CdnHost, objectName) + return +} +func GetSnapshot(videoPath, snapshotPath string, frameNum int) (snapshotName string, err error) { + buf := bytes.NewBuffer(nil) + zap.L().Info("GetSnapshot", zap.Any("videoPath", videoPath)) + err = ffmpeg.Input(videoPath). + Filter("select", ffmpeg.Args{fmt.Sprintf("gte(n,%d)", frameNum)}). + Output("pipe:", ffmpeg.KwArgs{"vframes": 1, "format": "image2", "vcodec": "mjpeg"}). + WithOutput(buf, os.Stdout). + Run() + if err != nil { + zap.L().Error("GetSnapshot Input err", zap.Error(err)) + return "", err + } + + img, err := imaging.Decode(buf) + if err != nil { + zap.L().Error("GetSnapshot Decode err", zap.Error(err)) + return "", err + } + + err = imaging.Save(img, snapshotPath+"."+PngType) + if err != nil { + zap.L().Error("GetSnapshot Save err", zap.Error(err)) + return "", err + } + + names := strings.Split(snapshotPath, "\\") + snapshotName = names[len(names)-1] + "." + PngType + return +} diff --git a/pkg/utils/picture.go b/pkg/utils/picture.go new file mode 100644 index 0000000..51d33d3 --- /dev/null +++ b/pkg/utils/picture.go @@ -0,0 +1,62 @@ +package utils + +import ( + "bytes" + "fmt" + "github.com/nfnt/resize" + "go.uber.org/zap" + "image" + "image/jpeg" + "os" +) + +const ( + CompressLimit = 1024 * 1024 * 1 + MaxHeight uint = 600 +) + +// CompressJPG 压缩图片,并返回缩略图路径 +func CompressJPG(dst string, newDst string) (err error) { + filebytes, err := os.ReadFile(dst) + if err != nil { + return err + } + compressbytes := compressImageResource(filebytes) + fo, err := os.Create(newDst) + defer fo.Close() + if err != nil { + return err + } + _, err = fo.Write(compressbytes) + if err != nil { + return err + } + return nil +} + +func compressImageResource(data []byte) []byte { + if len(data) < CompressLimit { + return data + } + img, _, err := image.Decode(bytes.NewReader(data)) + if err != nil { + return data + } + m := resize.Resize(0, MaxHeight, img, resize.Lanczos3) + buf := bytes.Buffer{} + + err = jpeg.Encode(&buf, m, &jpeg.Options{Quality: 100}) + if err != nil { + zap.L().Error("compressImageResource Encode err", zap.Error(err)) + return data + } + if buf.Len() > len(data) { + return data + } + fmt.Println(buf.Len()) + if buf.Len() >= CompressLimit { + bytes := compressImageResource(buf.Bytes()) + return bytes + } + return buf.Bytes() +} diff --git a/pkg/utils/untils.go b/pkg/utils/untils.go new file mode 100644 index 0000000..1eb42ee --- /dev/null +++ b/pkg/utils/untils.go @@ -0,0 +1,80 @@ +package utils + +import ( + "bytes" + "crypto/sha256" + "encoding/hex" + "errors" + "fonchain-fiee/pkg/e" + "io" + "io/ioutil" + "net/http" + "net/url" + "os" + "time" +) + +const ( + ExcelPrefix = "xlsx" +) + +func SHA256V(str []byte) string { + h := sha256.New() + h.Write(str) + return hex.EncodeToString(h.Sum(nil)) +} + +func Get(url string) string { + client := &http.Client{Timeout: 5 * time.Second} + resp, err := client.Get(url) + if err != nil { + panic(err) + } + defer resp.Body.Close() + var buffer [512]byte + result := bytes.NewBuffer(nil) + for { + n, err := resp.Body.Read(buffer[0:]) + result.Write(buffer[0:n]) + if err != nil && err == io.EOF { + break + } else if err != nil { + panic(err) + } + } + + return result.String() +} + +// PostForm 发送post请求 +func PostForm(urlStr string, data url.Values) (string, error) { + resp, err := http.PostForm(urlStr, data) + + if err != nil { + // handle error + } + defer resp.Body.Close() + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + // handle error + } + return string(body), err +} + +func CheckDirPath(path string, create bool) (exists bool, err error) { + exists = false + if path == "" { + err = errors.New(e.GetMsg(e.InvalidParams)) + return + } + if _, err = os.Stat(path); os.IsNotExist(err) { + if !create { + return + } + if err = os.MkdirAll(path, os.ModePerm); err != nil { + return + } + } + exists = true + return +}