feat: initial commit - Go + CGO captcha recognition service
Features: - Go + CGO ONNX/OpenCV wrapper for high performance - SQLite (default) / MySQL database support - Optional Redis caching - JWT authentication system - Multiple captcha recognition APIs: - OCR text recognition - Slider captcha matching - Image similarity comparison - Rotation captcha detection - Object detection - React frontend with install wizard - Docker and docker-compose support - Gitea CI/CD pipeline Project structure: - cmd/server: Main entry point - internal/: Core business logic - pkg/onnx: ONNX Runtime CGO wrapper - pkg/opencv: OpenCV CGO wrapper - web/: React frontend - deploy/: Deployment configs - scripts/: Utility scripts
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
Server ServerConfig
|
||||
Database DatabaseConfig
|
||||
Redis RedisConfig
|
||||
JWT JWTConfig
|
||||
Captcha CaptchaConfig
|
||||
}
|
||||
|
||||
type ServerConfig struct {
|
||||
Host string
|
||||
Port int
|
||||
Mode string
|
||||
}
|
||||
|
||||
type DatabaseConfig struct {
|
||||
Type string // sqlite or mysql
|
||||
Host string
|
||||
Port int
|
||||
User string
|
||||
Password string
|
||||
Database string
|
||||
SQLite SQLiteConfig
|
||||
}
|
||||
|
||||
type SQLiteConfig struct {
|
||||
Path string
|
||||
}
|
||||
|
||||
type RedisConfig struct {
|
||||
Enabled bool
|
||||
Host string
|
||||
Port int
|
||||
Password string
|
||||
DB int
|
||||
}
|
||||
|
||||
type JWTConfig struct {
|
||||
Secret string
|
||||
ExpireTime int // hours
|
||||
}
|
||||
|
||||
type CaptchaConfig struct {
|
||||
ModelPath string
|
||||
}
|
||||
|
||||
var Cfg *Config
|
||||
|
||||
func Load(configPath string) error {
|
||||
viper.SetConfigName("config")
|
||||
viper.SetConfigType("yaml")
|
||||
viper.AddConfigPath(".")
|
||||
viper.AddConfigPath("./data")
|
||||
viper.AddConfigPath(configPath)
|
||||
|
||||
// 默认值
|
||||
viper.SetDefault("server.host", "0.0.0.0")
|
||||
viper.SetDefault("server.port", 6688)
|
||||
viper.SetDefault("server.mode", "release")
|
||||
viper.SetDefault("database.type", "sqlite")
|
||||
viper.SetDefault("database.sqlite.path", "./data/app.db")
|
||||
viper.SetDefault("database.host", "localhost")
|
||||
viper.SetDefault("database.port", 3306)
|
||||
viper.SetDefault("redis.enabled", false)
|
||||
viper.SetDefault("redis.host", "localhost")
|
||||
viper.SetDefault("redis.port", 6379)
|
||||
viper.SetDefault("redis.db", 0)
|
||||
viper.SetDefault("jwt.expire_time", 1440) // 60 days
|
||||
viper.SetDefault("captcha.model_path", "./models")
|
||||
|
||||
if err := viper.ReadInConfig(); err != nil {
|
||||
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
|
||||
return fmt.Errorf("配置文件未找到,请先运行安装向导")
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
Cfg = &Config{}
|
||||
if err := viper.Unmarshal(Cfg); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 从环境变量读取 JWT Secret
|
||||
if secret := os.Getenv("JWT_SECRET"); secret != "" {
|
||||
Cfg.JWT.Secret = secret
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func Save(cfg *Config) error {
|
||||
viper.Set("server", cfg.Server)
|
||||
viper.Set("database", cfg.Database)
|
||||
viper.Set("redis", cfg.Redis)
|
||||
viper.Set("jwt", cfg.JWT)
|
||||
viper.Set("captcha", cfg.Captcha)
|
||||
|
||||
return viper.WriteConfig()
|
||||
}
|
||||
|
||||
func IsInstalled() bool {
|
||||
_, err := os.Stat("./data/config.yaml")
|
||||
return err == nil
|
||||
}
|
||||
Reference in New Issue
Block a user