feat: M0-M2 骨架落地(服务端/前端/宿主/数据库/积分引擎)
- server: Go 单二进制骨架,embed 内嵌前端,配置/迁移/HTTP 路由 - store: system.db + event.db 两套迁移,业务表 + 种子数据 - domain: 积分引擎(并列三口径/计分通道/流水/排名/破纪录)+ 68 个测试 - web: Vite + Vue 三入口骨架 + shared 层(类型/API/WebSocket 客户端) - console: Electron 宿主骨架(选屏/防熄屏/进程守护/托盘)
This commit is contained in:
1 parent
a61d793d79
commit
7d5d94f815
76 files changed
+10131
No files matched your search
@@ -0,0 +1,89 @@
|
||||
// Package config 负责加载服务端启动配置。
|
||||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
// Config 是 config.yaml 的映射。
|
||||
type Config struct {
|
||||
Server Server `yaml:"server"`
|
||||
DataDir string `yaml:"dataDir"`
|
||||
Log Log `yaml:"log"`
|
||||
}
|
||||
|
||||
// Server 是 HTTP 监听配置。
|
||||
type Server struct {
|
||||
Host string `yaml:"host"`
|
||||
Port int `yaml:"port"`
|
||||
}
|
||||
|
||||
// Log 是日志配置。
|
||||
type Log struct {
|
||||
Level string `yaml:"level"`
|
||||
}
|
||||
|
||||
// Default 返回一份可直接使用的默认配置。
|
||||
func Default() *Config {
|
||||
return &Config{
|
||||
Server: Server{Host: "0.0.0.0", Port: 8080},
|
||||
DataDir: "data",
|
||||
Log: Log{Level: "info"},
|
||||
}
|
||||
}
|
||||
|
||||
// Load 读取配置文件;文件不存在时返回默认配置。
|
||||
func Load(path string) (*Config, error) {
|
||||
cfg := Default()
|
||||
|
||||
raw, err := os.ReadFile(path)
|
||||
switch {
|
||||
case err == nil:
|
||||
if err := yaml.Unmarshal(raw, cfg); err != nil {
|
||||
return nil, fmt.Errorf("解析配置文件 %s: %w", path, err)
|
||||
}
|
||||
case os.IsNotExist(err):
|
||||
// 没有配置文件时使用默认值
|
||||
default:
|
||||
return nil, fmt.Errorf("读取配置文件 %s: %w", path, err)
|
||||
}
|
||||
|
||||
if err := cfg.validate(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
func (c *Config) validate() error {
|
||||
if c.Server.Port <= 0 || c.Server.Port > 65535 {
|
||||
return fmt.Errorf("server.port 非法: %d", c.Server.Port)
|
||||
}
|
||||
if strings.TrimSpace(c.DataDir) == "" {
|
||||
return fmt.Errorf("dataDir 不能为空")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Addr 返回 http.Server 使用的监听地址。
|
||||
func (s Server) Addr() string {
|
||||
return fmt.Sprintf("%s:%d", s.Host, s.Port)
|
||||
}
|
||||
|
||||
// SlogLevel 把配置里的日志级别映射为 slog 级别。
|
||||
func (l Log) SlogLevel() slog.Level {
|
||||
switch strings.ToLower(strings.TrimSpace(l.Level)) {
|
||||
case "debug":
|
||||
return slog.LevelDebug
|
||||
case "warn", "warning":
|
||||
return slog.LevelWarn
|
||||
case "error":
|
||||
return slog.LevelError
|
||||
default:
|
||||
return slog.LevelInfo
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user