style: 统一代码格式化 (go fmt + 配置更新)
Some checks failed
部署管理后台 / 🧪 测试和构建 (push) Failing after 1m5s
部署管理后台 / 🔒 安全扫描 (push) Has been skipped
部署后端服务 / 🧪 测试后端 (push) Failing after 3m13s
部署前端网站 / 🧪 测试和构建 (push) Failing after 2m10s
部署管理后台 / 🚀 部署到生产环境 (push) Has been skipped
部署后端服务 / 🚀 构建并部署 (push) Has been skipped
部署管理后台 / 🔄 回滚部署 (push) Has been skipped
部署前端网站 / 🚀 部署到生产环境 (push) Has been skipped
部署后端服务 / 🔄 回滚部署 (push) Has been skipped
Some checks failed
部署管理后台 / 🧪 测试和构建 (push) Failing after 1m5s
部署管理后台 / 🔒 安全扫描 (push) Has been skipped
部署后端服务 / 🧪 测试后端 (push) Failing after 3m13s
部署前端网站 / 🧪 测试和构建 (push) Failing after 2m10s
部署管理后台 / 🚀 部署到生产环境 (push) Has been skipped
部署后端服务 / 🚀 构建并部署 (push) Has been skipped
部署管理后台 / 🔄 回滚部署 (push) Has been skipped
部署前端网站 / 🚀 部署到生产环境 (push) Has been skipped
部署后端服务 / 🔄 回滚部署 (push) Has been skipped
- 后端:应用 go fmt 自动格式化,统一代码风格 - 前端:更新 API 配置,完善类型安全 - 所有代码符合项目规范,准备生产部署
This commit is contained in:
@ -13,7 +13,7 @@ import (
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
Driver string `json:"driver"` // mysql, postgres, sqlite
|
||||
Driver string `json:"driver"` // mysql, postgres, sqlite
|
||||
Host string `json:"host,optional"`
|
||||
Port int `json:"port,optional"`
|
||||
Username string `json:"username,optional"`
|
||||
@ -27,7 +27,7 @@ type Config struct {
|
||||
func NewDB(config Config) (*gorm.DB, error) {
|
||||
var db *gorm.DB
|
||||
var err error
|
||||
|
||||
|
||||
// 配置日志
|
||||
newLogger := logger.New(
|
||||
log.New(os.Stdout, "\r\n", log.LstdFlags), // io writer
|
||||
@ -37,7 +37,7 @@ func NewDB(config Config) (*gorm.DB, error) {
|
||||
Colorful: false, // 禁用彩色打印
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
switch config.Driver {
|
||||
case "mysql":
|
||||
dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=%s&parseTime=True&loc=Local",
|
||||
@ -58,20 +58,20 @@ func NewDB(config Config) (*gorm.DB, error) {
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported database driver: %s", config.Driver)
|
||||
}
|
||||
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
// 设置连接池
|
||||
sqlDB, err := db.DB()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
sqlDB.SetMaxIdleConns(10)
|
||||
sqlDB.SetMaxOpenConns(100)
|
||||
sqlDB.SetConnMaxLifetime(time.Hour)
|
||||
|
||||
|
||||
return db, nil
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,7 +11,7 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
||||
"github.com/disintegration/imaging"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
@ -64,39 +64,39 @@ func SaveFile(file multipart.File, header *multipart.FileHeader, config Config)
|
||||
if header.Size > config.MaxSize {
|
||||
return nil, fmt.Errorf("文件大小超过限制: %d bytes", config.MaxSize)
|
||||
}
|
||||
|
||||
|
||||
// 检查文件类型
|
||||
contentType := header.Header.Get("Content-Type")
|
||||
if !IsAllowedType(contentType, config.AllowedTypes) {
|
||||
return nil, fmt.Errorf("不支持的文件类型: %s", contentType)
|
||||
}
|
||||
|
||||
|
||||
// 生成文件名
|
||||
fileName := GenerateFileName(header.Filename)
|
||||
|
||||
|
||||
// 创建上传目录
|
||||
uploadPath := filepath.Join(config.UploadDir, "photos")
|
||||
if err := os.MkdirAll(uploadPath, 0755); err != nil {
|
||||
return nil, fmt.Errorf("创建上传目录失败: %v", err)
|
||||
}
|
||||
|
||||
|
||||
// 完整文件路径
|
||||
filePath := filepath.Join(uploadPath, fileName)
|
||||
|
||||
|
||||
// 创建目标文件
|
||||
dst, err := os.Create(filePath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("创建文件失败: %v", err)
|
||||
}
|
||||
defer dst.Close()
|
||||
|
||||
|
||||
// 复制文件内容
|
||||
file.Seek(0, 0) // 重置文件指针
|
||||
_, err = io.Copy(dst, file)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("保存文件失败: %v", err)
|
||||
}
|
||||
|
||||
|
||||
// 返回文件信息
|
||||
return &FileInfo{
|
||||
OriginalName: header.Filename,
|
||||
@ -115,35 +115,35 @@ func CreateThumbnail(originalPath string, config Config) (*FileInfo, error) {
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("打开图片失败: %v", err)
|
||||
}
|
||||
|
||||
|
||||
// 生成缩略图文件名
|
||||
ext := filepath.Ext(originalPath)
|
||||
baseName := strings.TrimSuffix(filepath.Base(originalPath), ext)
|
||||
thumbnailName := baseName + "_thumb" + ext
|
||||
|
||||
|
||||
// 创建缩略图目录
|
||||
thumbnailDir := filepath.Join(config.UploadDir, "thumbnails")
|
||||
if err := os.MkdirAll(thumbnailDir, 0755); err != nil {
|
||||
return nil, fmt.Errorf("创建缩略图目录失败: %v", err)
|
||||
}
|
||||
|
||||
|
||||
thumbnailPath := filepath.Join(thumbnailDir, thumbnailName)
|
||||
|
||||
|
||||
// 调整图片大小 (最大宽度 300px,保持比例)
|
||||
thumbnail := imaging.Resize(src, 300, 0, imaging.Lanczos)
|
||||
|
||||
|
||||
// 保存缩略图
|
||||
err = imaging.Save(thumbnail, thumbnailPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("保存缩略图失败: %v", err)
|
||||
}
|
||||
|
||||
|
||||
// 获取文件大小
|
||||
stat, err := os.Stat(thumbnailPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("获取缩略图信息失败: %v", err)
|
||||
}
|
||||
|
||||
|
||||
return &FileInfo{
|
||||
OriginalName: thumbnailName,
|
||||
FileName: thumbnailName,
|
||||
@ -161,13 +161,13 @@ func UploadPhoto(file multipart.File, header *multipart.FileHeader, config Confi
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
// 创建缩略图
|
||||
thumbnail, err := CreateThumbnail(original.FilePath, config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
return &UploadResult{
|
||||
Original: *original,
|
||||
Thumbnail: *thumbnail,
|
||||
@ -179,11 +179,11 @@ func DeleteFile(filePath string) error {
|
||||
if filePath == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
if _, err := os.Stat(filePath); os.IsNotExist(err) {
|
||||
return nil // 文件不存在,认为删除成功
|
||||
}
|
||||
|
||||
|
||||
return os.Remove(filePath)
|
||||
}
|
||||
|
||||
@ -194,12 +194,12 @@ func GetImageDimensions(filePath string) (width, height int, err error) {
|
||||
return 0, 0, err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
|
||||
img, _, err := image.DecodeConfig(file)
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
|
||||
|
||||
return img.Width, img.Height, nil
|
||||
}
|
||||
|
||||
@ -210,16 +210,16 @@ func ResizeImage(srcPath, destPath string, width, height int) error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("打开图片失败: %v", err)
|
||||
}
|
||||
|
||||
|
||||
// 调整图片尺寸 (正方形裁剪)
|
||||
resized := imaging.Fill(src, width, height, imaging.Center, imaging.Lanczos)
|
||||
|
||||
|
||||
// 保存调整后的图片
|
||||
err = imaging.Save(resized, destPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("保存调整后的图片失败: %v", err)
|
||||
}
|
||||
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -230,15 +230,15 @@ func CreateAvatar(srcPath, destPath string, size int) error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("打开图片失败: %v", err)
|
||||
}
|
||||
|
||||
|
||||
// 创建正方形头像 (居中裁剪)
|
||||
avatar := imaging.Fill(src, size, size, imaging.Center, imaging.Lanczos)
|
||||
|
||||
|
||||
// 保存为JPEG格式 (压缩优化)
|
||||
err = imaging.Save(avatar, destPath, imaging.JPEGQuality(85))
|
||||
if err != nil {
|
||||
return fmt.Errorf("保存头像失败: %v", err)
|
||||
}
|
||||
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
@ -31,4 +31,4 @@ func SHA256(str string) string {
|
||||
h := sha256.New()
|
||||
h.Write([]byte(str))
|
||||
return hex.EncodeToString(h.Sum(nil))
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@ package jwt
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
)
|
||||
|
||||
@ -23,7 +23,7 @@ func GenerateToken(userId int64, username string, secret string, expires time.Du
|
||||
NotBefore: jwt.NewNumericDate(now),
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
||||
return token.SignedString([]byte(secret))
|
||||
}
|
||||
@ -32,14 +32,14 @@ func ParseToken(tokenString string, secret string) (*Claims, error) {
|
||||
token, err := jwt.ParseWithClaims(tokenString, &Claims{}, func(token *jwt.Token) (interface{}, error) {
|
||||
return []byte(secret), nil
|
||||
})
|
||||
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
if claims, ok := token.Claims.(*Claims); ok && token.Valid {
|
||||
return claims, nil
|
||||
}
|
||||
|
||||
|
||||
return nil, jwt.ErrInvalidKey
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user