Files
jiang13-forum/config/config.go
freefire e1c1708715 初始提交:姜十三论坛 Jiang13 Forum
轻量自用论坛,Go 单二进制 + React SPA 内嵌 + SQLite。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-15 21:08:52 +08:00

82 lines
2.1 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package config
import (
"flag"
"fmt"
"os"
"path/filepath"
)
// Config 应用全局配置,通过命令行参数注入
type Config struct {
// 监听端口
Port int
// 数据目录SQLite 数据库、上传头像、日志文件均存放于此
DataDir string
// JWT 签名密钥
JWTSecret string
// 日志文件路径(相对 DataDir
LogFile string
}
// Parse 解析命令行参数并初始化目录
func Parse() (*Config, error) {
port := flag.Int("port", 3000, "HTTP 监听端口")
dataDir := flag.String("data", "./data", "数据存储目录(数据库、上传、日志)")
jwtSecret := flag.String("jwt-secret", "", "JWT 签名密钥(留空则自动生成并持久化)")
flag.Parse()
// 确保数据目录存在
if err := os.MkdirAll(*dataDir, 0755); err != nil {
return nil, fmt.Errorf("创建数据目录失败: %w", err)
}
uploadDir := filepath.Join(*dataDir, "uploads", "avatars")
if err := os.MkdirAll(uploadDir, 0755); err != nil {
return nil, fmt.Errorf("创建上传目录失败: %w", err)
}
cfg := &Config{
Port: *port,
DataDir: *dataDir,
JWTSecret: *jwtSecret,
LogFile: filepath.Join(*dataDir, "jiang13.log"),
}
// 处理 JWT 密钥持久化
secretFile := filepath.Join(*dataDir, ".jwt_secret")
if cfg.JWTSecret == "" {
if data, err := os.ReadFile(secretFile); err == nil && len(data) > 0 {
cfg.JWTSecret = string(data)
} else {
cfg.JWTSecret = generateRandomSecret(32)
_ = os.WriteFile(secretFile, []byte(cfg.JWTSecret), 0600)
}
}
return cfg, nil
}
// DBPath 返回 SQLite 数据库文件路径
func (c *Config) DBPath() string {
return filepath.Join(c.DataDir, "jiang13.db")
}
// UploadDir 返回头像上传目录
func (c *Config) UploadDir() string {
return filepath.Join(c.DataDir, "uploads", "avatars")
}
// FilterWordsPath 返回敏感词配置文件路径
func (c *Config) FilterWordsPath() string {
return filepath.Join(c.DataDir, "filter_words.txt")
}
func generateRandomSecret(n int) string {
const chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
b := make([]byte, n)
for i := range b {
b[i] = chars[i%len(chars)]
}
return string(b)
}