diff --git a/Dockerfile b/Dockerfile index 4c97ebf..8de9444 100644 --- a/Dockerfile +++ b/Dockerfile @@ -37,6 +37,9 @@ RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main . # 后端运行阶段 FROM alpine:latest AS backend +# 安装时区数据 +RUN apk add --no-cache tzdata + WORKDIR /root/ # 复制后端二进制文件 @@ -47,6 +50,7 @@ RUN mkdir -p uploads # 设置环境变量 ENV GIN_MODE=release +ENV TZ=Asia/Shanghai # 暴露端口 EXPOSE 8080 diff --git a/README.md b/README.md index 91ca9cb..5dafb9d 100644 --- a/README.md +++ b/README.md @@ -187,6 +187,9 @@ DB_NAME=url_db # 服务器配置 PORT=8080 + +# 时区配置 +TIMEZONE=Asia/Shanghai ``` ### Docker 服务说明 diff --git a/common/alipan.go b/common/alipan.go index 9c50b21..6e34b08 100644 --- a/common/alipan.go +++ b/common/alipan.go @@ -3,7 +3,6 @@ package pan import ( "encoding/json" "fmt" - "log" "os" "path/filepath" "sync" @@ -84,7 +83,7 @@ func (a *AlipanService) Transfer(shareID string) (*TransferResult, error) { config := a.config a.configMutex.RUnlock() - log.Printf("开始处理阿里云盘分享: %s", shareID) + fmt.Printf("开始处理阿里云盘分享: %s", shareID) // 获取access token accessToken, err := a.manageAccessToken() diff --git a/docker-compose.yml b/docker-compose.yml index 7e7da1c..3311eed 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -28,6 +28,7 @@ services: DB_PASSWORD: password DB_NAME: url_db PORT: 8080 + TIMEZONE: Asia/Shanghai depends_on: postgres: condition: service_healthy diff --git a/env.example b/env.example index 1f0585b..ada9647 100644 --- a/env.example +++ b/env.example @@ -9,6 +9,9 @@ DB_NAME=url_db PORT=8080 GIN_MODE=release +# 时区配置 +TIMEZONE=Asia/Shanghai + # 文件上传配置 UPLOAD_DIR=./uploads MAX_FILE_SIZE=100MB \ No newline at end of file diff --git a/handlers/stats_handler.go b/handlers/stats_handler.go index 0a72e30..0247273 100644 --- a/handlers/stats_handler.go +++ b/handlers/stats_handler.go @@ -24,7 +24,7 @@ func GetStats(c *gin.Context) { // 获取今日更新数量 var todayUpdates int64 - today := time.Now().Format("2006-01-02") + today := utils.GetCurrentTime().Format("2006-01-02") db.DB.Model(&entity.Resource{}).Where("DATE(updated_at) = ?", today).Count(&todayUpdates) SuccessResponse(c, gin.H{ @@ -65,7 +65,7 @@ func GetPerformanceStats(c *gin.Context) { } SuccessResponse(c, gin.H{ - "timestamp": time.Now().Unix(), + "timestamp": utils.GetCurrentTime().Unix(), "memory": gin.H{ "alloc": m.Alloc, "total_alloc": m.TotalAlloc, @@ -89,7 +89,7 @@ func GetPerformanceStats(c *gin.Context) { func GetSystemInfo(c *gin.Context) { SuccessResponse(c, gin.H{ "uptime": time.Since(startTime).String(), - "start_time": startTime.Format("2006-01-02 15:04:05"), + "start_time": utils.FormatTime(startTime, "2006-01-02 15:04:05"), "version": utils.Version, "environment": gin.H{ "gin_mode": gin.Mode(), @@ -98,4 +98,4 @@ func GetSystemInfo(c *gin.Context) { } // 记录启动时间 -var startTime = time.Now() +var startTime = utils.GetCurrentTime() diff --git a/handlers/version_handler.go b/handlers/version_handler.go index c7eb2c7..2005af2 100644 --- a/handlers/version_handler.go +++ b/handlers/version_handler.go @@ -28,7 +28,7 @@ func GetVersion(c *gin.Context) { Success: true, Data: versionInfo, Message: "版本信息获取成功", - Time: time.Now(), + Time: utils.GetCurrentTime(), } c.JSON(http.StatusOK, response) @@ -44,7 +44,7 @@ func GetVersionString(c *gin.Context) { "version": versionString, }, Message: "版本字符串获取成功", - Time: time.Now(), + Time: utils.GetCurrentTime(), } c.JSON(http.StatusOK, response) @@ -60,7 +60,7 @@ func GetFullVersionInfo(c *gin.Context) { "version_info": fullInfo, }, Message: "完整版本信息获取成功", - Time: time.Now(), + Time: utils.GetCurrentTime(), } c.JSON(http.StatusOK, response) @@ -89,7 +89,7 @@ func CheckUpdate(c *gin.Context) { "update_url": "https://github.com/ctwj/urldb/releases/latest", }, Message: "更新检查完成", - Time: time.Now(), + Time: utils.GetCurrentTime(), } c.JSON(http.StatusOK, response) diff --git a/main.go b/main.go index dcc09c0..b7a5e11 100644 --- a/main.go +++ b/main.go @@ -28,6 +28,9 @@ func main() { utils.Info("未找到.env文件,使用默认配置") } + // 初始化时区设置 + utils.InitTimezone() + // 设置Gin运行模式 ginMode := os.Getenv("GIN_MODE") if ginMode == "" { diff --git a/middleware/auth.go b/middleware/auth.go index ea4c239..7970c17 100644 --- a/middleware/auth.go +++ b/middleware/auth.go @@ -94,9 +94,9 @@ func GenerateToken(user *entity.User) (string, error) { Username: user.Username, Role: user.Role, RegisteredClaims: jwt.RegisteredClaims{ - ExpiresAt: jwt.NewNumericDate(time.Now().Add(30 * 24 * time.Hour)), // 30天有效期 - IssuedAt: jwt.NewNumericDate(time.Now()), - NotBefore: jwt.NewNumericDate(time.Now()), + ExpiresAt: jwt.NewNumericDate(utils.GetCurrentTime().Add(30 * 24 * time.Hour)), // 30天有效期 + IssuedAt: jwt.NewNumericDate(utils.GetCurrentTime()), + NotBefore: jwt.NewNumericDate(utils.GetCurrentTime()), }, } diff --git a/utils/log_viewer.go b/utils/log_viewer.go index f8c88a1..2f85264 100644 --- a/utils/log_viewer.go +++ b/utils/log_viewer.go @@ -269,7 +269,7 @@ func (lv *LogViewer) CleanOldLogs(days int) error { return err } - cutoffTime := time.Now().AddDate(0, 0, -days) + cutoffTime := GetCurrentTime().AddDate(0, 0, -days) deletedCount := 0 for _, file := range files { diff --git a/utils/logger.go b/utils/logger.go index d9256b8..a360ab9 100644 --- a/utils/logger.go +++ b/utils/logger.go @@ -153,7 +153,7 @@ func (l *Logger) initLogFile() error { } // 创建新的日志文件 - logFile := filepath.Join(l.config.LogDir, fmt.Sprintf("app_%s.log", time.Now().Format("2006-01-02"))) + logFile := filepath.Join(l.config.LogDir, fmt.Sprintf("app_%s.log", GetCurrentTime().Format("2006-01-02"))) file, err := os.OpenFile(logFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) if err != nil { return fmt.Errorf("创建日志文件失败: %v", err) @@ -291,8 +291,8 @@ func (l *Logger) rotateLog() { } // 重命名当前日志文件 - currentLogFile := filepath.Join(l.config.LogDir, fmt.Sprintf("app_%s.log", time.Now().Format("2006-01-02"))) - backupLogFile := filepath.Join(l.config.LogDir, fmt.Sprintf("app_%s_%s.log", time.Now().Format("2006-01-02"), time.Now().Format("15-04-05"))) + currentLogFile := filepath.Join(l.config.LogDir, fmt.Sprintf("app_%s.log", GetCurrentTime().Format("2006-01-02"))) + backupLogFile := filepath.Join(l.config.LogDir, fmt.Sprintf("app_%s_%s.log", GetCurrentTime().Format("2006-01-02"), GetCurrentTime().Format("15-04-05"))) if _, err := os.Stat(currentLogFile); err == nil { os.Rename(currentLogFile, backupLogFile) @@ -314,7 +314,7 @@ func (l *Logger) cleanOldLogs() { return } - cutoffTime := time.Now().AddDate(0, 0, -l.config.MaxAge) + cutoffTime := GetCurrentTime().AddDate(0, 0, -l.config.MaxAge) for _, file := range files { fileInfo, err := os.Stat(file) diff --git a/utils/scheduler.go b/utils/scheduler.go index 9894f5e..b68811f 100644 --- a/utils/scheduler.go +++ b/utils/scheduler.go @@ -777,7 +777,7 @@ func (s *Scheduler) processAutoTransfer() { Error("转存资源失败 (ID: %d): %v", res.ID, err) } else { Info("成功转存资源: %s", res.Title) - rand.Seed(time.Now().UnixNano()) + rand.Seed(GetCurrentTime().UnixNano()) sleepSec := rand.Intn(3) + 1 // 1,2,3 time.Sleep(time.Duration(sleepSec) * time.Second) } @@ -793,7 +793,7 @@ func (s *Scheduler) getResourcesForTransfer(config *entity.SystemConfig, quarkPa days := config.AutoTransferLimitDays var sinceTime time.Time if days > 0 { - sinceTime = time.Now().AddDate(0, 0, -days) + sinceTime = GetCurrentTime().AddDate(0, 0, -days) } else { sinceTime = time.Time{} } diff --git a/utils/timezone.go b/utils/timezone.go new file mode 100644 index 0000000..4987ff4 --- /dev/null +++ b/utils/timezone.go @@ -0,0 +1,55 @@ +package utils + +import ( + "os" + "time" +) + +// InitTimezone 初始化时区设置 +func InitTimezone() { + // 从环境变量获取时区配置 + timezone := os.Getenv("TIMEZONE") + if timezone == "" { + // 默认使用上海时间 + timezone = "Asia/Shanghai" + Info("未配置时区,使用默认时区: %s", timezone) + } else { + Info("使用配置的时区: %s", timezone) + } + + // 设置时区 + loc, err := time.LoadLocation(timezone) + if err != nil { + Error("加载时区失败: %v,使用系统默认时区", err) + return + } + + // 设置全局时区 + time.Local = loc + Info("时区设置成功: %s", timezone) +} + +// GetCurrentTime 获取当前时间(使用配置的时区) +func GetCurrentTime() time.Time { + return time.Now() +} + +// GetCurrentTimeString 获取当前时间字符串(使用配置的时区) +func GetCurrentTimeString() string { + return time.Now().Format("2006-01-02 15:04:05") +} + +// GetCurrentTimeRFC3339 获取当前时间RFC3339格式(使用配置的时区) +func GetCurrentTimeRFC3339() string { + return time.Now().Format(time.RFC3339) +} + +// ParseTime 解析时间字符串(使用配置的时区) +func ParseTime(timeStr string) (time.Time, error) { + return time.Parse("2006-01-02 15:04:05", timeStr) +} + +// FormatTime 格式化时间(使用配置的时区) +func FormatTime(t time.Time, layout string) string { + return t.Format(layout) +} diff --git a/utils/version.go b/utils/version.go index fcf9251..9ff9b43 100644 --- a/utils/version.go +++ b/utils/version.go @@ -24,7 +24,7 @@ type VersionInfo struct { // 编译时注入的版本信息 var ( Version = getVersionFromFile() - BuildTime = time.Now().Format("2006-01-02 15:04:05") + BuildTime = GetCurrentTimeString() GitCommit = "unknown" GitBranch = "unknown" ) @@ -40,7 +40,7 @@ func getVersionFromFile() string { // GetVersionInfo 获取版本信息 func GetVersionInfo() *VersionInfo { - buildTime, _ := time.Parse("2006-01-02 15:04:05", BuildTime) + buildTime, _ := ParseTime(BuildTime) return &VersionInfo{ Version: Version, @@ -72,7 +72,7 @@ func GetFullVersionInfo() string { Node版本: %s 平台: %s/%s`, info.Version, - info.BuildTime.Format("2006-01-02 15:04:05"), + FormatTime(info.BuildTime, "2006-01-02 15:04:05"), info.GitCommit, info.GitBranch, info.GoVersion,