国展报名
This commit is contained in:
parent
0772e8d0da
commit
e45f0591ab
56
cmd/app.go
Normal file
56
cmd/app.go
Normal file
@ -0,0 +1,56 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
appConfig "github.com/exhibition-main/internal/config"
|
||||
"github.com/exhibition-main/pkg/router"
|
||||
"github.com/exhibition-main/pkg/service"
|
||||
"github.com/exhibition-main/pkg/tracing"
|
||||
"github.com/exhibition-main/pkg/utils"
|
||||
"github.com/go-redis/redis"
|
||||
|
||||
"github.com/robfig/cron/v3"
|
||||
"github.com/streadway/amqp"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type App struct {
|
||||
lg *zap.Logger
|
||||
RedisClient *redis.Client
|
||||
JaegerTracer *tracing.JaegerProvider
|
||||
RabbitMqLink *amqp.Connection
|
||||
}
|
||||
|
||||
func NewApp(lg *zap.Logger, RedisClient *redis.Client, JaegerTracer *tracing.JaegerProvider) *App {
|
||||
return &App{
|
||||
lg: lg,
|
||||
RedisClient: RedisClient,
|
||||
JaegerTracer: JaegerTracer,
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
_, err := InitApp()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
modules()
|
||||
r := router.NewRouter()
|
||||
if appConfig.Data.System.IsHttps {
|
||||
_ = r.RunTLS(fmt.Sprintf(":%d", appConfig.Data.System.Port), appConfig.Data.System.CertPath, appConfig.Data.System.KeyPath)
|
||||
} else {
|
||||
_ = r.Run(fmt.Sprintf(":%d", appConfig.Data.System.Port))
|
||||
}
|
||||
select {}
|
||||
}
|
||||
|
||||
func modules() {
|
||||
if err := utils.InitTrans("zh"); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if appConfig.Data.System.Cron {
|
||||
c := cron.New()
|
||||
service.Task(c)
|
||||
c.Start()
|
||||
}
|
||||
}
|
17
cmd/wire.go
Normal file
17
cmd/wire.go
Normal file
@ -0,0 +1,17 @@
|
||||
// go:build wireinject
|
||||
//go:build wireinject
|
||||
// +build wireinject
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/exhibition-main/pkg/cache"
|
||||
"github.com/exhibition-main/pkg/logger"
|
||||
"github.com/exhibition-main/pkg/tracing"
|
||||
"github.com/google/wire"
|
||||
)
|
||||
|
||||
func InitApp() (*App, error) {
|
||||
wire.Build(logger.Provider, cache.RedisProvider, tracing.Provider, NewApp)
|
||||
return &App{}, nil
|
||||
}
|
23
cmd/wire_gen.go
Normal file
23
cmd/wire_gen.go
Normal file
@ -0,0 +1,23 @@
|
||||
// Code generated by Wire. DO NOT EDIT.
|
||||
|
||||
//go:generate go run github.com/google/wire/cmd/wire
|
||||
//go:build !wireinject
|
||||
// +build !wireinject
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/exhibition-main/pkg/cache"
|
||||
"github.com/exhibition-main/pkg/logger"
|
||||
"github.com/exhibition-main/pkg/tracing"
|
||||
)
|
||||
|
||||
// Injectors from wire.go:
|
||||
|
||||
func InitApp() (*App, error) {
|
||||
zapLogger := logger.ZapInit()
|
||||
client := cache.NewRedis()
|
||||
jaegerProvider := tracing.NewTracing()
|
||||
app := NewApp(zapLogger, client, jaegerProvider)
|
||||
return app, nil
|
||||
}
|
@ -11,7 +11,10 @@ dubbo:
|
||||
max-call-send-msg-size: 8000000
|
||||
max-call-recv-msg-size: 8000000
|
||||
references:
|
||||
|
||||
ExhibitionClientImpl:
|
||||
protocol: tri
|
||||
filter: tps
|
||||
interface: com.fontree.microservices.common.Exhibition
|
||||
logger:
|
||||
zap-config:
|
||||
level: error # 日志级别
|
||||
|
@ -11,7 +11,10 @@ dubbo:
|
||||
max-call-send-msg-size: 8000000
|
||||
max-call-recv-msg-size: 8000000
|
||||
references:
|
||||
|
||||
ExhibitionClientImpl:
|
||||
protocol: tri
|
||||
filter: tps
|
||||
interface: com.fontree.microservices.common.Exhibition
|
||||
logger:
|
||||
zap-config:
|
||||
level: error # 日志级别
|
||||
|
@ -11,7 +11,10 @@ dubbo:
|
||||
max-call-send-msg-size: 8000000
|
||||
max-call-recv-msg-size: 8000000
|
||||
references:
|
||||
|
||||
ExhibitionClientImpl:
|
||||
protocol: tri
|
||||
filter: tps
|
||||
interface: com.fontree.microservices.common.Exhibition
|
||||
logger:
|
||||
zap-config:
|
||||
level: error # 日志级别
|
||||
|
26
go.mod
26
go.mod
@ -2,12 +2,25 @@ module github.com/exhibition-main
|
||||
|
||||
go 1.20
|
||||
|
||||
replace (
|
||||
github.com/fonchain_enterprise/utils/aes => ../utils/aes
|
||||
github.com/fonchain_enterprise/utils/chain => ../utils/chain
|
||||
github.com/fonchain_enterprise/utils/feie => ../utils/feie
|
||||
github.com/fonchain_enterprise/utils/ipAddrQuery => ../utils/ipAddrQuery
|
||||
github.com/fonchain_enterprise/utils/jwt => ../utils/jwt
|
||||
github.com/fonchain_enterprise/utils/logger => ../utils/logger
|
||||
github.com/fonchain_enterprise/utils/objstorage => ../utils/objstorage
|
||||
github.com/fonchain_enterprise/utils/rand => ../utils/rand
|
||||
github.com/fonchain_enterprise/utils/utils => ../utils/utils
|
||||
)
|
||||
|
||||
require (
|
||||
dubbo.apache.org/dubbo-go/v3 v3.0.5
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
||||
github.com/dubbogo/gost v1.13.2
|
||||
github.com/dubbogo/grpc-go v1.42.10
|
||||
github.com/dubbogo/triple v1.2.2-rc2
|
||||
github.com/fonchain_enterprise/utils/objstorage v0.0.0-00010101000000-000000000000
|
||||
github.com/gin-contrib/gzip v0.0.6
|
||||
github.com/gin-contrib/pprof v1.4.0
|
||||
github.com/gin-gonic/gin v1.9.0
|
||||
@ -19,12 +32,17 @@ require (
|
||||
github.com/google/wire v0.5.0
|
||||
github.com/mwitkow/go-proto-validators v0.3.2
|
||||
github.com/natefinch/lumberjack v2.0.0+incompatible
|
||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
|
||||
github.com/opentracing/opentracing-go v1.2.0
|
||||
github.com/robfig/cron/v3 v3.0.1
|
||||
github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd
|
||||
github.com/satori/go.uuid v1.2.0
|
||||
github.com/spf13/viper v1.7.0
|
||||
github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271
|
||||
github.com/u2takey/ffmpeg-go v0.5.0
|
||||
github.com/uber/jaeger-client-go v2.30.0+incompatible
|
||||
go.uber.org/zap v1.21.0
|
||||
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8
|
||||
google.golang.org/protobuf v1.28.1
|
||||
)
|
||||
|
||||
@ -36,8 +54,12 @@ 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.1704 // indirect
|
||||
github.com/aliyun/aliyun-oss-go-sdk v2.2.4+incompatible // indirect
|
||||
github.com/apache/dubbo-getty v1.4.9-0.20221022181821-4dc6252ce98c // indirect
|
||||
github.com/apache/dubbo-go-hessian2 v1.11.5 // indirect
|
||||
github.com/aws/aws-sdk-go v1.38.20 // indirect
|
||||
github.com/baidubce/bce-sdk-go v0.9.123 // indirect
|
||||
github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/bits-and-blooms/bitset v1.2.0 // indirect
|
||||
github.com/buger/jsonparser v1.1.1 // indirect
|
||||
@ -112,7 +134,7 @@ require (
|
||||
github.com/prometheus/statsd_exporter v0.21.0 // indirect
|
||||
github.com/shirou/gopsutil/v3 v3.22.2 // indirect
|
||||
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||
github.com/spf13/afero v1.1.2 // indirect
|
||||
github.com/spf13/afero v1.2.2 // indirect
|
||||
github.com/spf13/cast v1.3.0 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.0.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
@ -120,6 +142,7 @@ require (
|
||||
github.com/tklauser/go-sysconf v0.3.10 // indirect
|
||||
github.com/tklauser/numcpus v0.4.0 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/u2takey/go-utils v0.3.1 // indirect
|
||||
github.com/uber/jaeger-lib v2.4.1+incompatible // indirect
|
||||
github.com/ugorji/go/codec v1.2.9 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.2 // indirect
|
||||
@ -138,6 +161,7 @@ require (
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect
|
||||
golang.org/x/sys v0.5.0 // indirect
|
||||
golang.org/x/text v0.7.0 // indirect
|
||||
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9 // indirect
|
||||
google.golang.org/appengine v1.6.6 // indirect
|
||||
google.golang.org/genproto v0.0.0-20220504150022-98cd25cafc72 // indirect
|
||||
google.golang.org/grpc v1.51.0 // indirect
|
||||
|
@ -10,6 +10,79 @@ import (
|
||||
|
||||
var Data = new(AppConfig)
|
||||
|
||||
var (
|
||||
AppMode string
|
||||
HttpPort string
|
||||
Key string
|
||||
Cert string
|
||||
IsHttps bool
|
||||
RunHttps bool
|
||||
Domain string
|
||||
OssDomain string
|
||||
ServerDM string
|
||||
Env string
|
||||
DriverUrl string
|
||||
AppointUrl string
|
||||
MaterialHost string
|
||||
BosAk string
|
||||
BosSk string
|
||||
BosBucketName string
|
||||
BosBaseDir string
|
||||
BosUrl string
|
||||
BosHttp string
|
||||
BosDomain string
|
||||
ProjectMapDir string
|
||||
JaegerHost string
|
||||
JaegerOpen bool
|
||||
Cron bool
|
||||
DingAccessToken string
|
||||
DingUrl string
|
||||
HolidayID string
|
||||
HolidaySecret string
|
||||
HolidaySingleUrl string
|
||||
HolidayMultiUrl string
|
||||
|
||||
ErpAk string
|
||||
ErpSk string
|
||||
|
||||
// rabbitmq
|
||||
RabbitmqUser string
|
||||
RabbitmqPassword string
|
||||
RabbitmqHost string
|
||||
RabbitmqPort int
|
||||
RabbitmqVhost string
|
||||
RabbitmqVhostArtwork string
|
||||
|
||||
RedisDB int
|
||||
RedisAddr string
|
||||
RedisPw string
|
||||
|
||||
//shop配置
|
||||
ShopHost string
|
||||
//ShopDetail string
|
||||
|
||||
// 地图
|
||||
MapAppCode string
|
||||
// es
|
||||
ElasticHost string
|
||||
SendIndexesUrl string
|
||||
ChatGptHost string
|
||||
|
||||
ApiHost string
|
||||
|
||||
Level string
|
||||
Filename string
|
||||
MaxSize string
|
||||
MaxAge string
|
||||
MaxBackups string
|
||||
|
||||
YearGiftCheckHost string
|
||||
Aliyun struct {
|
||||
AccessKeyId string
|
||||
AccessKeySecret string
|
||||
}
|
||||
)
|
||||
|
||||
type AppConfig struct {
|
||||
System struct {
|
||||
Domain string
|
||||
@ -42,6 +115,15 @@ type AppConfig struct {
|
||||
Key string
|
||||
Expire int32
|
||||
}
|
||||
Bos struct {
|
||||
AccessKeyId string
|
||||
AccessKeySecret string
|
||||
Endpoint string
|
||||
Host string
|
||||
BucketName string
|
||||
BosBaseDir string
|
||||
CdnHost string
|
||||
}
|
||||
}
|
||||
|
||||
func GetConf() (iniConf string, err error) {
|
||||
|
12
internal/model/baidu.go
Normal file
12
internal/model/baidu.go
Normal file
@ -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"`
|
||||
}
|
@ -6,10 +6,28 @@ const (
|
||||
MODE_ENV = "MODE_ENV"
|
||||
)
|
||||
|
||||
const (
|
||||
HttpType = "http://"
|
||||
HttpsType = "https://"
|
||||
TmpArtworkDir = "./runtime/tmp/artworks"
|
||||
TmpArtistDir = "./runtime/tmp/artists"
|
||||
MediaPath = "./runtime/"
|
||||
TplPath = "./data/"
|
||||
ImgActionRotate = "rotate" //旋转
|
||||
MediaTypeVideo = "video"
|
||||
MediaTypeImage = "video"
|
||||
)
|
||||
|
||||
type Response struct {
|
||||
Status int `json:"status"`
|
||||
Data interface{} `json:"data"`
|
||||
Msg string `json:"msg"`
|
||||
Code int `json:"code"`
|
||||
Error error `json:"error"`
|
||||
Err string `json:"err"`
|
||||
Keys []string `json:"keys"`
|
||||
Mark string `json:"mark,omitempty"`
|
||||
Page *PageInfo `json:"page,omitempty"`
|
||||
}
|
||||
|
||||
type PageInfo struct {
|
||||
|
@ -24,5 +24,12 @@ const (
|
||||
|
||||
NEED_LOGIN = "请先登录"
|
||||
|
||||
INVALID_TOKEN = "token不合法"
|
||||
INVALID_TOKEN = "token不合法"
|
||||
INVALID_PARAMS = "参数错误"
|
||||
JSON_UNMARSHAL = "Json解析错误"
|
||||
|
||||
ERROR_BAIDU_IMAGE = "图片审核不通过"
|
||||
ERROR_BAIDU_FAIL = "图片审核失败"
|
||||
|
||||
ErrorUploadBos
|
||||
)
|
||||
|
@ -1,9 +1,12 @@
|
||||
package response
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/exhibition-main/internal/model"
|
||||
"github.com/exhibition-main/internal/msg"
|
||||
"github.com/gin-gonic/gin"
|
||||
"net/http"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
func ResponseMsg(c *gin.Context, httpCode int, Resp model.Response) {
|
||||
@ -25,3 +28,158 @@ func ResponseQuickMsg(c *gin.Context, Status uint8, Msg string, Data interface{}
|
||||
Data: Data,
|
||||
})
|
||||
}
|
||||
|
||||
func Success(c *gin.Context, datas ...interface{}) {
|
||||
var data any
|
||||
if datas != nil {
|
||||
data = datas[0]
|
||||
}
|
||||
dataFieldStr, _ := c.Get("dataField")
|
||||
key := []string{"*"}
|
||||
|
||||
if dataFieldStr != "" && dataFieldStr != nil {
|
||||
dataField := dataFieldStr.([]string)
|
||||
key = dataField
|
||||
|
||||
if len(dataField) == 1 && dataField[0] == "*" { //不做处理
|
||||
|
||||
} else if len(dataField) >= 1 {
|
||||
isList := isList(reflect.TypeOf(data).Elem())
|
||||
|
||||
// 是列表返回
|
||||
if isList == false {
|
||||
ChangeFromReflect(data, dataField)
|
||||
} else {
|
||||
ChangeRawFromReflect(data, dataField)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, model.Response{
|
||||
Status: msg.Ok,
|
||||
Code: msg.StatusOK,
|
||||
Data: data,
|
||||
// Keys: dataField,
|
||||
Keys: key,
|
||||
})
|
||||
c.Abort()
|
||||
}
|
||||
|
||||
func IsContainString(items []string, item string) bool {
|
||||
for _, eachItem := range items {
|
||||
if eachItem == item {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func ChangeFromReflect(data interface{}, dataField []string) {
|
||||
m := reflect.TypeOf(data).Elem()
|
||||
for i := 0; i < m.NumField(); i++ {
|
||||
fieldType := m.Field(i)
|
||||
if IsContainString(dataField, fieldType.Name) == false {
|
||||
field := reflect.ValueOf(data).Elem().FieldByName(fieldType.Name)
|
||||
|
||||
switch m.Field(i).Type.Name() {
|
||||
case "int":
|
||||
if field.CanSet() {
|
||||
field.SetInt(0)
|
||||
}
|
||||
case "uint":
|
||||
if field.CanSet() {
|
||||
field.SetUint(0)
|
||||
}
|
||||
case "uint64":
|
||||
if field.CanSet() {
|
||||
field.SetUint(0)
|
||||
}
|
||||
case "string":
|
||||
if field.CanSet() {
|
||||
field.SetString("")
|
||||
}
|
||||
default:
|
||||
if reflect.ValueOf(data).Elem().FieldByName(fieldType.Name).CanAddr() {
|
||||
if reflect.ValueOf(data).Elem().FieldByName(fieldType.Name).Kind() == reflect.Slice {
|
||||
field := reflect.ValueOf(data).Elem().FieldByName(fieldType.Name)
|
||||
|
||||
if field.CanSet() {
|
||||
field.Set(reflect.MakeSlice(field.Type(), 0, 0))
|
||||
}
|
||||
}
|
||||
|
||||
if reflect.ValueOf(data).Elem().FieldByName(fieldType.Name).Kind() == reflect.Struct {
|
||||
}
|
||||
|
||||
if reflect.ValueOf(data).Elem().FieldByName(fieldType.Name).Kind() == reflect.Ptr {
|
||||
field := reflect.ValueOf(data).Elem().FieldByName(fieldType.Name)
|
||||
if !reflect.ValueOf(data).Elem().FieldByName(fieldType.Name).IsNil() {
|
||||
fieldType := reflect.ValueOf(data).Elem().FieldByName(fieldType.Name).Elem().Type()
|
||||
|
||||
if field.CanSet() {
|
||||
field.Set(reflect.New(fieldType))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func ChangeRawFromReflect(data interface{}, dataField []string) {
|
||||
|
||||
sliceContent := reflect.ValueOf(data).Elem().FieldByName("Data")
|
||||
for i := 0; i < sliceContent.Len(); i++ {
|
||||
sliceContent.Index(i)
|
||||
ChangeFromReflect(sliceContent.Index(i).Interface(), dataField)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func isList(m reflect.Type) bool {
|
||||
dataExist := false
|
||||
|
||||
for i := 0; i < m.NumField(); i++ {
|
||||
|
||||
fieldType := m.Field(i)
|
||||
|
||||
if fieldType.Name == "Data" {
|
||||
getValue := reflect.ValueOf(fieldType)
|
||||
|
||||
if getValue.Kind() != reflect.Slice {
|
||||
dataExist = true
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return dataExist
|
||||
}
|
||||
|
||||
// Error 统一错误返回
|
||||
func Error(c *gin.Context, code int, err error, message ...string) {
|
||||
|
||||
fmt.Println("err:", err)
|
||||
status := msg.Fail
|
||||
if code == msg.StatusUnauthorized {
|
||||
status = msg.StatusUnauthorized
|
||||
}
|
||||
var msgStr string
|
||||
if message != nil {
|
||||
msgStr = message[0]
|
||||
} else if err != nil {
|
||||
msgStr = err.Error()
|
||||
}
|
||||
c.JSON(msg.StatusOK, model.Response{
|
||||
Status: status,
|
||||
Msg: msgStr,
|
||||
Data: nil,
|
||||
})
|
||||
|
||||
c.Abort()
|
||||
}
|
||||
|
58
pkg/logic/baidu.go
Normal file
58
pkg/logic/baidu.go
Normal file
@ -0,0 +1,58 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/dubbogo/gost/log/logger"
|
||||
"github.com/exhibition-main/internal/model"
|
||||
"github.com/exhibition-main/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
|
||||
}
|
119
pkg/logic/upload.go
Normal file
119
pkg/logic/upload.go
Normal file
@ -0,0 +1,119 @@
|
||||
package logic
|
||||
|
||||
import (
|
||||
"github.com/dubbogo/gost/log/logger"
|
||||
"github.com/rwcarlsen/goexif/exif"
|
||||
"golang.org/x/image/bmp"
|
||||
"image"
|
||||
"image/jpeg"
|
||||
"image/png"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// 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
|
||||
}
|
@ -2,6 +2,8 @@ package router
|
||||
|
||||
import (
|
||||
"github.com/exhibition-main/internal/middleware"
|
||||
"github.com/exhibition-main/pkg/service"
|
||||
"github.com/exhibition-main/pkg/service/common"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-contrib/gzip"
|
||||
@ -16,49 +18,20 @@ func NewRouter() *gin.Engine {
|
||||
r.Use(gzip.Gzip(gzip.DefaultCompression))
|
||||
//加入日志中间件,跨域中间件
|
||||
r.Use(middleware.NewLogger(), middleware.Cors(), middleware.GinRecovery(true))
|
||||
//noAuth := r.Group("")
|
||||
auth := r.Group("")
|
||||
auth.Use(middleware.JWTAuthMiddleware())
|
||||
//userAuth := auth.Group("user")
|
||||
//{
|
||||
// userAuth.POST("info", api.UserInfo)
|
||||
// userAuth.POST("tickets", api.Tickets)
|
||||
// userAuth.POST("login-out", api.LoginOut)
|
||||
// userAuth.POST("destroy", api.Destroy)
|
||||
//}
|
||||
//userNoAuth := noAuth.Group("user")
|
||||
//{
|
||||
// userNoAuth.POST("login", api.Login)
|
||||
//}
|
||||
//goodsAuth := auth.Group("goods")
|
||||
//{
|
||||
// goodsAuth.POST("drink-list", api.DrinkList)
|
||||
// goodsAuth.POST("ticket-list", api.TickerList)
|
||||
// goodsAuth.POST("set-meal-list", api.SetMealList)
|
||||
//}
|
||||
//
|
||||
//orderAuth := auth.Group("order")
|
||||
//{
|
||||
// orderAuth.POST("buy-goods", api.BuyGoods)
|
||||
// orderAuth.POST("buy-tickets", api.BuyTicket)
|
||||
// orderAuth.POST("buy-balance", api.BuyBalance)
|
||||
// orderAuth.POST("buy-set-meal", api.BuySetMeal)
|
||||
// orderAuth.POST("history-goods", api.HistoryGoods)
|
||||
// orderAuth.POST("history-tickets", api.HistoryTickets)
|
||||
// orderAuth.POST("history-balance", api.HistoryBalance)
|
||||
//}
|
||||
//
|
||||
//orderNoAuth := noAuth.Group("order")
|
||||
//{
|
||||
// orderNoAuth.POST("wx_callback", api.WxCallback)
|
||||
// orderAuth.POST("order-data-h5", api.OrderDataH5)
|
||||
// orderAuth.POST("update-h5-order", api.UpdateH5Order)
|
||||
//}
|
||||
//
|
||||
//miniNoAuth := noAuth.Group("mini")
|
||||
//{
|
||||
// miniNoAuth.POST("url-scheme", api.UrlScheme)
|
||||
//}
|
||||
// 上传
|
||||
upload := auth.Group("upload")
|
||||
{
|
||||
upload.POST("img", common.UploadImg)
|
||||
}
|
||||
|
||||
registerAuth := auth.Group("register")
|
||||
{
|
||||
registerAuth.POST("register_record_list", service.RegisterRecordList)
|
||||
registerAuth.POST("check_by_phone", service.CheckPhone)
|
||||
registerAuth.POST("save_register_info", service.SaveRegisterRecord)
|
||||
}
|
||||
|
||||
//静态文件
|
||||
r.StaticFS("/static", http.Dir("./runtime"))
|
||||
|
309
pkg/service/common/common.go
Normal file
309
pkg/service/common/common.go
Normal file
@ -0,0 +1,309 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/disintegration/imaging"
|
||||
"github.com/dubbogo/gost/log/logger"
|
||||
"github.com/exhibition-main/internal/config"
|
||||
"github.com/exhibition-main/internal/model"
|
||||
"github.com/exhibition-main/internal/msg"
|
||||
"github.com/exhibition-main/internal/response"
|
||||
"github.com/exhibition-main/pkg/logic"
|
||||
"github.com/exhibition-main/pkg/utils"
|
||||
"github.com/fonchain_enterprise/utils/objstorage"
|
||||
"github.com/gin-gonic/gin"
|
||||
uuid "github.com/satori/go.uuid"
|
||||
ffmpeg "github.com/u2takey/ffmpeg-go"
|
||||
"go.uber.org/zap"
|
||||
"io/ioutil"
|
||||
"mime/multipart"
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var (
|
||||
wg sync.WaitGroup
|
||||
)
|
||||
|
||||
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
|
||||
source := c.PostForm("source")
|
||||
mask := c.PostForm("mask")
|
||||
action := c.PostForm("action")
|
||||
if mask == "" {
|
||||
mask = "default"
|
||||
}
|
||||
mediaType := c.PostForm("type")
|
||||
logger.Errorf("UploadImg 1 %+v", 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 {
|
||||
response.ResponseQuickMsg(c, msg.Fail, errS.Error(), nil)
|
||||
return
|
||||
}
|
||||
}
|
||||
logger.Errorf("UploadImg 2 %+v", mask)
|
||||
// 检验参数
|
||||
if mask == "" || source == "" {
|
||||
response.ResponseQuickMsg(c, msg.Fail, msg.INVALID_PARAMS, nil)
|
||||
return
|
||||
}
|
||||
file, err := c.FormFile("file")
|
||||
// 检验文件
|
||||
if err != nil {
|
||||
logger.Errorf("Upload FormFile err", err)
|
||||
response.ResponseQuickMsg(c, msg.Fail, err.Error(), nil)
|
||||
return
|
||||
}
|
||||
logger.Errorf("UploadImg 3 %+v", mask)
|
||||
// 判断是不是视频或者需要压缩
|
||||
var oriUrl string
|
||||
if isCompress != 1 && mediaType != "video" && action == "" {
|
||||
oriUrl, err = quickBos(file, mediaType, mask, source)
|
||||
if err != nil {
|
||||
response.ResponseQuickMsg(c, msg.Fail, err.Error(), nil)
|
||||
return
|
||||
}
|
||||
response.ResponseQuickMsg(c, msg.Ok, msg.SUCCESS, map[string]interface{}{
|
||||
"ori_url": oriUrl,
|
||||
})
|
||||
return
|
||||
}
|
||||
logger.Errorf("UploadImg 4 %+v", mask)
|
||||
//创建文件名
|
||||
fileExt := strings.ToLower(path.Ext(file.Filename))
|
||||
filename := uuid.NewV4()
|
||||
if err != nil {
|
||||
response.ResponseQuickMsg(c, msg.Fail, err.Error(), nil)
|
||||
return
|
||||
}
|
||||
fileFullName := fmt.Sprintf("%s%s", filename, fileExt)
|
||||
//检测文件夹 不存在就创建
|
||||
imgPath := fmt.Sprintf("%s/%s/%s", BasePath, source, mask)
|
||||
_, err = utils.CheckDirPath(imgPath, true)
|
||||
if err != nil {
|
||||
response.ResponseQuickMsg(c, msg.Fail, err.Error(), nil)
|
||||
return
|
||||
}
|
||||
dst := fmt.Sprintf("%s/%s", imgPath, fileFullName)
|
||||
logger.Errorf("UploadImg 5 %+v", mask)
|
||||
// 保存文件至指定路径
|
||||
err = c.SaveUploadedFile(file, dst)
|
||||
if err != nil {
|
||||
logger.Errorf("Upload FormFile err", err)
|
||||
response.ResponseQuickMsg(c, msg.Fail, err.Error(), nil)
|
||||
return
|
||||
}
|
||||
logger.Errorf("UploadImg 6 %+v", mask)
|
||||
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 {
|
||||
logger.Errorf("Upload compress err", err)
|
||||
response.ResponseQuickMsg(c, msg.Fail, err.Error(), data)
|
||||
return
|
||||
}
|
||||
data["compress_url"] = compressUrl
|
||||
}
|
||||
logger.Errorf("UploadImg 7 %+v", mask)
|
||||
// 如果是视频需要截图图片做封面
|
||||
if mediaType == VideoType {
|
||||
videoCover := fmt.Sprintf("%s/%s", imgPath, filename)
|
||||
_, err = GetSnapshot(dst, videoCover, 1)
|
||||
if err != nil {
|
||||
logger.Errorf("GetSnapshot err %+v", err.Error())
|
||||
response.ResponseQuickMsg(c, msg.Fail, "获取封面失败", err.Error())
|
||||
return
|
||||
}
|
||||
logger.Errorf("UploadImg 8 %+v", mask)
|
||||
logger.Errorf("UploadImg 8.1 videoCover %+v", 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)
|
||||
data["cover_url"] = coverUrl
|
||||
if err != nil {
|
||||
logger.Errorf("Upload GetSnapshot err", zap.Error(err))
|
||||
response.ResponseQuickMsg(c, msg.Fail, err.Error(), nil)
|
||||
return
|
||||
}
|
||||
}
|
||||
ossUrl, err := PutBos(dst, mediaType, true)
|
||||
if err != nil {
|
||||
response.ResponseQuickMsg(c, msg.Fail, err.Error(), nil)
|
||||
return
|
||||
}
|
||||
data["ori_url"] = ossUrl
|
||||
response.ResponseQuickMsg(c, msg.Ok, msg.SUCCESS, data)
|
||||
return
|
||||
}
|
||||
|
||||
func GetSnapshot(videoPath, snapshotPath string, frameNum int) (snapshotName string, err error) {
|
||||
buf := bytes.NewBuffer(nil)
|
||||
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 {
|
||||
logger.Errorf("GetSnapshot Input err:", zap.Error(err))
|
||||
return "", err
|
||||
}
|
||||
|
||||
img, err := imaging.Decode(buf)
|
||||
if err != nil {
|
||||
logger.Errorf("GetSnapshot Decode err:", zap.Error(err))
|
||||
return "", err
|
||||
}
|
||||
|
||||
err = imaging.Save(img, snapshotPath+"."+PngType)
|
||||
if err != nil {
|
||||
logger.Errorf("GetSnapshot Save err:", zap.Error(err))
|
||||
return "", err
|
||||
}
|
||||
|
||||
names := strings.Split(snapshotPath, "\\")
|
||||
snapshotName = names[len(names)-1] + "." + PngType
|
||||
return
|
||||
}
|
||||
|
||||
func PutBos(filePath string, mediaType string, needRemove bool) (url string, err error) {
|
||||
BOSClient, err := objstorage.NewBOS(config.BosAk, config.BosSk, objstorage.BOS_BJ)
|
||||
if err != nil {
|
||||
logger.Errorf("PutBos NewBOS err ", err)
|
||||
err = errors.New(msg.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)
|
||||
}
|
||||
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.BosBaseDir, config.Env, filePath)
|
||||
_, err = BOSClient.PutObjectFromBytes(config.BosBucketName, objectName, fileBytes)
|
||||
if err != nil {
|
||||
logger.Errorf("PutBos PutObject err %+v", err.Error())
|
||||
err = errors.New(msg.ErrorUploadBos)
|
||||
return
|
||||
}
|
||||
//url = fmt.Sprintf("%s%s%s/%s", config.BosHttp, config.BosBucketName, config.BosUrl, objectName)
|
||||
url = fmt.Sprintf("%s%s/%s", config.BosHttp, config.BosDomain, objectName)
|
||||
return
|
||||
}
|
||||
|
||||
func quickBos(file *multipart.FileHeader, mediaType string, mask string, source string) (url string, err error) {
|
||||
newFile, _ := file.Open()
|
||||
defer newFile.Close()
|
||||
uuids := uuid.NewV4()
|
||||
filePath := fmt.Sprintf("%s/%s/%s/%s%s", mediaType, mask, source, uuids, filepath.Ext(file.Filename))
|
||||
fileBytes, _ := ioutil.ReadAll(newFile)
|
||||
if mediaType == "image" {
|
||||
if err = BaiduCheckImage(fileBytes); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
var objectName string = fmt.Sprintf("%s/%s/%s", config.BosBaseDir, config.Env, filePath)
|
||||
BOSClient, _ := objstorage.NewBOS(config.BosAk, config.BosSk, objstorage.BOS_BJ)
|
||||
_, err = BOSClient.PutObjectFromBytes(config.BosBucketName, objectName, fileBytes)
|
||||
if err != nil {
|
||||
logger.Errorf("quickBos err", err)
|
||||
return
|
||||
}
|
||||
//url = fmt.Sprintf("%s%s%s/%s", config.BosHttp, config.BosBucketName, config.BosUrl, objectName)
|
||||
url = fmt.Sprintf("%s%s/%s", config.BosHttp, config.BosDomain, 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(msg.JSON_UNMARSHAL)
|
||||
return
|
||||
}
|
||||
logger.Error("user_defined res", res)
|
||||
if res.ErrorCode != 0 || res.ErrorMsg != "" {
|
||||
return errors.New(msg.ERROR_BAIDU_FAIL)
|
||||
}
|
||||
if res.Conclusion != "合规" && res.Conclusion != "疑似" {
|
||||
return errors.New(msg.ERROR_BAIDU_IMAGE)
|
||||
}
|
||||
return nil
|
||||
}
|
14
pkg/service/cron.go
Normal file
14
pkg/service/cron.go
Normal file
@ -0,0 +1,14 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"dubbo.apache.org/dubbo-go/v3/config"
|
||||
"github.com/robfig/cron/v3"
|
||||
)
|
||||
|
||||
func Task(c *cron.Cron) {
|
||||
if config.GetConsumerService("ArtworkClientImpl") != nil {
|
||||
_, _ = c.AddFunc("@every 5m", func() {
|
||||
|
||||
})
|
||||
}
|
||||
}
|
@ -3,13 +3,14 @@ package service
|
||||
import (
|
||||
"dubbo.apache.org/dubbo-go/v3/config"
|
||||
_ "dubbo.apache.org/dubbo-go/v3/imports"
|
||||
"github.com/exhibition-main/api/exhibition"
|
||||
appConfig "github.com/exhibition-main/internal/config"
|
||||
)
|
||||
|
||||
//var GrpcAccountClientImpl = new(account.AccountClientImpl)
|
||||
var GrpcExhibitionClientImpl = new(exhibition.ExhibitionClientImpl)
|
||||
|
||||
func init() {
|
||||
//config.SetConsumerService(GrpcAccountClientImpl)
|
||||
config.SetConsumerService(GrpcExhibitionClientImpl)
|
||||
appConfig.GetOptions()
|
||||
if err := config.Load(); err != nil {
|
||||
panic(err)
|
||||
|
@ -1 +1,61 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/dubbogo/gost/log/logger"
|
||||
"github.com/exhibition-main/api/exhibition"
|
||||
"github.com/exhibition-main/internal/msg"
|
||||
"github.com/exhibition-main/internal/response"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func RegisterRecordList(c *gin.Context) {
|
||||
var recordListReq exhibition.RecordListReq
|
||||
if err := c.ShouldBind(&recordListReq); err != nil {
|
||||
logger.Errorf("RegisterRecordList ShouldBind err", err)
|
||||
response.ResponseQuickMsg(c, msg.Fail, msg.INVALID_PARAMS, nil)
|
||||
return
|
||||
}
|
||||
resp, err := GrpcExhibitionClientImpl.RegisterRecordList(context.Background(), &recordListReq)
|
||||
if err != nil {
|
||||
response.ResponseQuickMsg(c, msg.Fail, err.Error(), nil)
|
||||
return
|
||||
}
|
||||
response.ResponseQuickMsg(c, msg.Ok, resp.Msg, resp)
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
func CheckPhone(c *gin.Context) {
|
||||
var registerInfo exhibition.RegisterInfo
|
||||
if err := c.ShouldBind(®isterInfo); err != nil {
|
||||
logger.Errorf("CheckPhone ShouldBind err", err)
|
||||
response.ResponseQuickMsg(c, msg.Fail, msg.INVALID_PARAMS, nil)
|
||||
return
|
||||
}
|
||||
resp, err := GrpcExhibitionClientImpl.CheckPhone(context.Background(), ®isterInfo)
|
||||
if err != nil {
|
||||
response.ResponseQuickMsg(c, msg.Fail, err.Error(), nil)
|
||||
return
|
||||
}
|
||||
response.ResponseQuickMsg(c, msg.Ok, resp.Msg, resp)
|
||||
return
|
||||
|
||||
}
|
||||
|
||||
func SaveRegisterRecord(c *gin.Context) {
|
||||
var registerInfo exhibition.RegisterInfo
|
||||
if err := c.ShouldBind(®isterInfo); err != nil {
|
||||
logger.Errorf("SaveRegisterRecord ShouldBind err", err)
|
||||
response.ResponseQuickMsg(c, msg.Fail, msg.INVALID_PARAMS, nil)
|
||||
return
|
||||
}
|
||||
resp, err := GrpcExhibitionClientImpl.SaveRegisterRecord(context.Background(), ®isterInfo)
|
||||
if err != nil {
|
||||
response.ResponseQuickMsg(c, msg.Fail, err.Error(), nil)
|
||||
return
|
||||
}
|
||||
response.ResponseQuickMsg(c, msg.Ok, resp.Msg, resp)
|
||||
return
|
||||
|
||||
}
|
||||
|
82
pkg/utils/picture.go
Normal file
82
pkg/utils/picture.go
Normal file
@ -0,0 +1,82 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/exhibition-main/internal/msg"
|
||||
"github.com/nfnt/resize"
|
||||
"go.uber.org/zap"
|
||||
"image"
|
||||
"image/jpeg"
|
||||
"os"
|
||||
)
|
||||
|
||||
const (
|
||||
CompressLimit = 1024 * 1024 * 1
|
||||
MaxHeight uint = 600
|
||||
)
|
||||
|
||||
func CheckDirPath(path string, create bool) (exists bool, err error) {
|
||||
exists = false
|
||||
if path == "" {
|
||||
err = errors.New(msg.INVALID_PARAMS)
|
||||
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
|
||||
}
|
||||
|
||||
// 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()
|
||||
}
|
47
pkg/utils/untils.go
Normal file
47
pkg/utils/untils.go
Normal file
@ -0,0 +1,47 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
)
|
||||
|
||||
// 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 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()
|
||||
}
|
Loading…
Reference in New Issue
Block a user