package bootstrap import ( "fmt" "os" "path/filepath" "github.com/break/junhong_cmp_fiber/pkg/config" "go.uber.org/zap" ) type DirectoryResult struct { TempDir string AppLogDir string AccessLogDir string Fallbacks []string } func EnsureDirectories(cfg *config.Config, logger *zap.Logger) (*DirectoryResult, error) { result := &DirectoryResult{} directories := []struct { path string configKey string resultPtr *string }{ {cfg.Storage.TempDir, "storage.temp_dir", &result.TempDir}, {filepath.Dir(cfg.Logging.AppLog.Filename), "logging.app_log.filename", &result.AppLogDir}, {filepath.Dir(cfg.Logging.AccessLog.Filename), "logging.access_log.filename", &result.AccessLogDir}, } for _, dir := range directories { if dir.path == "" || dir.path == "." { continue } actualPath, fallback, err := ensureDirectory(dir.path, logger) if err != nil { return nil, fmt.Errorf("创建目录 %s (%s) 失败: %w", dir.path, dir.configKey, err) } *dir.resultPtr = actualPath if fallback { result.Fallbacks = append(result.Fallbacks, actualPath) } } return result, nil } func ensureDirectory(path string, logger *zap.Logger) (actualPath string, fallback bool, err error) { if err := os.MkdirAll(path, 0755); err != nil { if os.IsPermission(err) { fallbackPath := filepath.Join(os.TempDir(), "junhong", filepath.Base(path)) if mkErr := os.MkdirAll(fallbackPath, 0755); mkErr != nil { return "", false, fmt.Errorf("原路径 %s 权限不足,降级路径 %s 也创建失败: %w", path, fallbackPath, mkErr) } if logger != nil { logger.Warn("目录权限不足,使用降级路径", zap.String("original", path), zap.String("fallback", fallbackPath), ) } return fallbackPath, true, nil } return "", false, err } return path, false, nil }