feat: 🤪 cdn配置

main
tian 2 years ago
parent fcf1c23b6f
commit 97ee6fd5f2

@ -62,7 +62,7 @@ func (b *BaseApi) Captcha(c *gin.Context) {
type GetCDNTokenQuery struct {
Method string `form:"method"`
SaveKey string `form:"save_key"`
SaveKey string `form:"saveKey"`
}
type GetCDNTokenData struct {
@ -95,7 +95,7 @@ func (b *BaseApi) GetCDNToken(c *gin.Context) {
return
}
token, err = upyun.GetUpYunFormAPIToken(q.Method, q.SaveKey)
token, err = upyun.GetUpyunToken(q.Method, q.SaveKey)
if err != nil {
global.GVA_LOG.Error("获取失败!", zap.Error(err))
response.FailWithMessage("获取失败", c)
@ -106,7 +106,7 @@ func (b *BaseApi) GetCDNToken(c *gin.Context) {
data.Method = token.Method
data.Policy = token.Policy
data.Expiration = token.XUpYunExpire
response.OkWithData(gin.H{"data": data}, c)
response.OkWithData(data, c)
}
}

@ -67,12 +67,15 @@ db-list:
log-zap: false
disable: true
email:
to: xxx@qq.com
from: xxx@163.com
host: smtp.163.com
to: 184391138@qq.com
from: m13160998425@163.com
# host: smtp.gmail.com # 587
# host: smtp.163.com # 25
host: smtp.mxhichina.com # 25
secret: xxx
nickname: test
port: 465
# port: 587
port: 25
is-ssl: true
excel:
dir: ./resource/excel/
@ -212,3 +215,7 @@ zap:
max-age: 0
show-line: true
log-in-console: true
cdn:
bucket: pychr
op: pychr
password: 9Vk9Mdxkh8zFQ24c6rysPxv3Sjm1IF3L

@ -0,0 +1,7 @@
package config
type CDN struct {
Bucket string `mapstructure:"bucket" json:"bucket" yaml:"bucket"`
Op string `mapstructure:"op" json:"op" yaml:"op"`
Password string `mapstructure:"password" json:"password" yaml:"password"`
}

@ -29,4 +29,5 @@ type Server struct {
// 跨域配置
Cors CORS `mapstructure:"cors" json:"cors" yaml:"cors"`
CDN CDN `mapstructure:"cdn" json:"cdn" yaml:"cdn"`
}

@ -2,6 +2,7 @@ package initialize
import (
"os"
"pychr/model/goods"
"pychr/global"
"pychr/model/example"
@ -9,7 +10,6 @@ import (
"go.uber.org/zap"
"gorm.io/gorm"
"pychr/model/goods"
)
func Gorm() *gorm.DB {
@ -47,12 +47,12 @@ func RegisterTables() {
system.SysAuthorityBtn{},
system.SysAutoCode{},
system.SysExportTemplate{},
system.GoodsShow{},
example.ExaFile{},
example.ExaCustomer{},
example.ExaFileChunk{},
example.ExaFileUploadAndDownload{}, goods.GoodsShow{},
example.ExaFileUploadAndDownload{},
goods.GoodsShow{},
)
if err != nil {
global.GVA_LOG.Error("register table failed", zap.Error(err))

@ -11,15 +11,15 @@ type GoodsShow struct {
global.GVA_MODEL
LangType common.LangType `json:"langType" form:"langType" gorm:"column:lang_type;comment:语言类型 1中文 2英文;size:10;" binding:"required"` // 语言类型 1中文 2英文
LangTypeName string `json:"langTypeName" form:"langTypeName"` // 语言类型名称
GoodsMainPic string `json:"goodsMainPic" form:"goodsMainPic" gorm:"column:goods_main_pic;comment:商品主图;size:191;"` // 商品主图
GoodsMainPic string `json:"goodsMainPic" form:"goodsMainPic" gorm:"column:goods_main_pic;comment:商品主图;type:longtext;"` // 商品主图
Name string `json:"name" form:"name" gorm:"column:name;comment:商品名称;size:191;" binding:"required"` // 商品名称
BriefIntroduction string `json:"briefIntroduction" form:"briefIntroduction" gorm:"column:brief_introduction;comment:简介;size:191;"` // 简介
Type int `json:"type" form:"type" gorm:"column:type;comment:类型;size:10;" binding:"required"` // 类型
TypeName string `json:"typeName"` // 类型名称
MainIntroduction string `json:"mainIntroduction" form:"mainIntroduction" gorm:"column:main_introduction;comment:主介绍;size:191;"` // 主介绍
GoodsAssistantPic string `json:"goodsAssistantPic" form:"goodsAssistantPic" gorm:"column:goods_assistantPic;comment:商品副图;size:191;"` // 商品副图
GoodsAssistantPic string `json:"goodsAssistantPic" form:"goodsAssistantPic" gorm:"column:goods_assistantPic;comment:商品副图;type:longtext;"` // 商品副图
SecondIntroductionTitle string `json:"secondIntroductionTitle" form:"secondIntroductionTitle" gorm:"column:second_introduction_title;comment:副介绍标题;size:191;"` // 副介绍标题
SecondIntroduction string `json:"secondIntroduction" form:"secondIntroduction" gorm:"column:second_introduction;comment:副介绍,逗号拼接;size:191;"` // 副介绍,逗号拼接
SecondIntroduction string `json:"secondIntroduction" form:"secondIntroduction" gorm:"column:second_introduction;comment:副介绍,逗号拼接;type:longtext;"` // 副介绍,逗号拼接
}
// TableName 商品 GoodsShow自定义表名 goods_show

@ -26,20 +26,3 @@ type SysUser struct {
func (SysUser) TableName() string {
return "sys_users"
}
type GoodsShow struct {
global.GVA_MODEL
LangType int `json:"langType" gorm:"default:1;comment:语言类型 1中文 2英文"` // 语言类型 1中文 2英文
GoodsMainPic string `json:"goodsMainPic" gorm:"comment:商品主图"` // 商品主图
Name string `json:"name" gorm:"index;comment:商品名称"` // 商品名称
BriefIntroduction string `json:"briefIntroduction" gorm:"comment:简介"` // 简介
Type int `json:"type" gorm:"default:1;comment:类型"` // 类型
MainIntroduction string `json:"mainIntroduction" gorm:"default:dark;comment:主介绍"` // 主介绍
GoodsAssistantPic string `json:"goodsAssistantPic" gorm:"default:'';comment:商品副图"` // 商品副图
SecondIntroductionTitle string `json:"secondIntroductionTitle" gorm:"default:'';comment:副介绍标题"` // 副介绍标题
SecondIntroduction string `json:"secondIntroduction" gorm:"comment:副介绍"` // 副介绍,逗号拼接
}
func (GoodsShow) TableName() string {
return "goods_show"
}

@ -5,100 +5,91 @@ import (
"crypto/md5"
"crypto/sha1"
"encoding/base64"
"encoding/hex"
"encoding/json"
"fmt"
"strconv"
"pychr/global"
"strings"
"time"
)
var (
bucket = "pychr"
op = "root"
password = "MRnhPT4VlGXAuDEWe4l7JTxrdxbXjZFE"
token = "2cb96a90-b787-43a4-91ec-54d796c069da"
)
const (
effectiveDuration = time.Minute * 60
effectiveDuration = time.Minute * 30
)
type RestAPIToken struct {
Authorization string
XUpYunUriPrefix string
XUpYunExpire int64
}
func GetUpYunRestAPIUploadToken(method string) (r RestAPIToken) {
now := time.Now()
expire := now.Add(effectiveDuration).Unix()
elem := FilterNoneString([]string{"PUT", "/" + bucket, strconv.FormatInt(expire, 10)})
p := strings.Join(elem, "&")
key := []byte(StringMD5(password))
mac := hmac.New(sha1.New, key)
mac.Write([]byte(p))
hash := mac.Sum(nil)
sign := base64.StdEncoding.EncodeToString(hash)
authorization := "UPYUN " + op + ":" + sign
r.XUpYunExpire = expire
r.Authorization = authorization
r.XUpYunUriPrefix = "/" + bucket
return
}
type FormAPIToken struct {
Bucket string
Method string
Authorization string
XUpYunExpire int64
Policy string
Date string
}
func GetUpYunFormAPIToken(method, saveKey string) (r FormAPIToken, err error) {
method = strings.ToUpper(method)
now := time.Now()
expiration := now.Add(effectiveDuration).Unix()
type Policy struct {
Bucket string `json:"bucket"`
SaveKey string `json:"save-key"`
Expiration int64 `json:"expiration"`
// ContentMD5 string `json:"content-md5"`
}
paramsFormat := `{"bucket": "%v", "expiration": %v, "save-key": "%v"}`
params := fmt.Sprintf(paramsFormat, bucket, expiration, saveKey)
func makeSaveKey() string {
return "/{year}/{mon}/{day}/upload_{random32}{.suffix}"
}
policy := StringBase64(params)
func makePolicy(bucket, saveKey string) (string, int64) {
expiration := time.Now().Add(effectiveDuration).Unix()
obj := Policy{
Bucket: bucket,
SaveKey: saveKey,
Expiration: expiration,
// ContentMD5: content-md5,
}
elem := FilterNoneString([]string{method, "/" + bucket, policy})
p := strings.Join(elem, "&")
key := []byte(StringMD5(password))
mac := hmac.New(sha1.New, key)
mac.Write([]byte(p))
hash := mac.Sum(nil)
sign := base64.StdEncoding.EncodeToString(hash)
authorization := "UPYUN " + op + ":" + sign
str, err := json.Marshal(&obj)
if err != nil {
return "", 0
}
r.Bucket = bucket
r.Method = method
r.XUpYunExpire = expiration
r.Authorization = authorization
r.Policy = policy
return
sEnc := base64.StdEncoding.EncodeToString([]byte(str))
return sEnc, expiration
}
func FilterNoneString(list []string) (r []string) {
for _, t := range list {
if t != "" {
r = append(r, t)
func md5Str(s string) string {
return fmt.Sprintf("%x", md5.Sum([]byte(s)))
}
func makeRFC1123Date(d time.Time) string {
utc := d.UTC().Format(time.RFC1123)
return strings.Replace(utc, "UTC", "GMT", -1)
}
func base64ToStr(b []byte) string {
return base64.StdEncoding.EncodeToString(b)
}
func sign(key, secret, method, uri, date, policy, md5 string) string {
mac := hmac.New(sha1.New, []byte(secret))
elems := []string{}
for _, v := range []string{method, uri, date, policy, md5} {
if v != "" {
elems = append(elems, v)
}
}
return
value := strings.Join(elems, "&")
mac.Write([]byte(value))
signStr := base64ToStr(mac.Sum(nil))
return "UPYUN " + key + ":" + signStr
}
// 生成字符串MD5
func StringMD5(s string) string {
h := md5.New()
h.Write([]byte(s))
return hex.EncodeToString(h.Sum(nil))
}
func GetUpyunToken(method, saveKey string) (r FormAPIToken, err error) {
method = strings.ToUpper(method)
date := makeRFC1123Date(time.Now())
policy, expiration := makePolicy(global.GVA_CONFIG.CDN.Bucket, saveKey)
authorization := sign(global.GVA_CONFIG.CDN.Bucket, md5Str(global.GVA_CONFIG.CDN.Password), method, "/"+global.GVA_CONFIG.CDN.Bucket, "", policy, "")
r.Bucket = global.GVA_CONFIG.CDN.Bucket
r.Method = method
r.XUpYunExpire = expiration
r.Authorization = authorization
r.Policy = policy
r.Date = date
func StringBase64(s string) (r string) {
return base64.StdEncoding.EncodeToString([]byte(s))
return
}

Loading…
Cancel
Save