feat: 优化配置和文件上传

- 上传文件名添加唯一ID避免覆盖
- 支持通过环境变量配置 JWT 密钥和 Token 过期时间
- 支持通过环境变量覆盖管理员账号(可选)
This commit is contained in:
clz
2026-01-11 19:11:47 +08:00
parent fb5b46f90c
commit c242694d9b
3 changed files with 74 additions and 3 deletions

View File

@@ -5,6 +5,7 @@ import (
"fmt"
"os"
"path/filepath"
"strconv"
"gopkg.in/yaml.v3"
)
@@ -260,6 +261,50 @@ func Load() {
if cleanedColl := os.Getenv("MONGO_CLEANED_COLLECTION"); cleanedColl != "" {
Global.MongoCleanedCollection = cleanedColl
}
// 认证相关环境变量覆盖
if jwtSecret := os.Getenv("JWT_SECRET"); jwtSecret != "" {
Global.JWTSecret = jwtSecret
}
if tokenExpiry := os.Getenv("TOKEN_EXPIRY"); tokenExpiry != "" {
if expiry, err := strconv.Atoi(tokenExpiry); err == nil && expiry > 0 {
Global.TokenExpiry = expiry
}
}
// 管理员账号环境变量覆盖(覆盖配置文件中的第一个用户)
adminUser := os.Getenv("ADMIN_USERNAME")
adminPass := os.Getenv("ADMIN_PASSWORD")
if adminUser != "" && adminPass != "" {
adminName := os.Getenv("ADMIN_NAME")
if adminName == "" {
adminName = "管理员"
}
adminEmail := os.Getenv("ADMIN_EMAIL")
if adminEmail == "" {
adminEmail = adminUser + "@billai.com"
}
// 查找并更新 admin 用户,或添加新用户
found := false
for i := range Global.Users {
if Global.Users[i].Username == adminUser || Global.Users[i].Role == "admin" {
Global.Users[i].Username = adminUser
Global.Users[i].Password = adminPass
Global.Users[i].Name = adminName
Global.Users[i].Email = adminEmail
Global.Users[i].Role = "admin"
found = true
break
}
}
if !found {
Global.Users = append(Global.Users, UserInfo{
Username: adminUser,
Password: adminPass,
Name: adminName,
Email: adminEmail,
Role: "admin",
})
}
}
}
// ResolvePath 解析路径(相对路径转为绝对路径)

View File

@@ -1,6 +1,8 @@
package handler
import (
"crypto/rand"
"encoding/hex"
"fmt"
"io"
"net/http"
@@ -52,9 +54,16 @@ func Upload(c *gin.Context) {
}
billType := req.Type
// 3. 保存上传的文件
// 3. 保存上传的文件添加唯一ID避免覆盖
timestamp := time.Now().Format("20060102_150405")
inputFileName := fmt.Sprintf("%s_%s", timestamp, header.Filename)
uniqueID := generateShortID()
// 获取文件扩展名和基础名
ext := filepath.Ext(header.Filename)
baseName := header.Filename[:len(header.Filename)-len(ext)]
// 文件名格式: 时间戳_唯一ID_原始文件名
inputFileName := fmt.Sprintf("%s_%s_%s%s", timestamp, uniqueID, baseName, ext)
uploadDirAbs := config.ResolvePath(config.Global.UploadDir)
inputPath := filepath.Join(uploadDirAbs, inputFileName)
@@ -182,3 +191,13 @@ func generateFileSequence(dir, timestamp, billType, ext string) string {
}
return fmt.Sprintf("%03d", len(matches)+1)
}
// generateShortID 生成 6 位随机唯一标识符
func generateShortID() string {
bytes := make([]byte, 3) // 3 字节 = 6 个十六进制字符
if _, err := rand.Read(bytes); err != nil {
// 如果随机数生成失败,使用时间纳秒作为备选
return fmt.Sprintf("%06x", time.Now().UnixNano()%0xFFFFFF)
}
return hex.EncodeToString(bytes)
}