16844d4a42
- Added AI configuration options to .env.example and config.go for OpenAI integration. - Implemented Redis caching for session management in main.go and auth middleware. - Updated smoke logging service to support real smoking time (`smoke_at`) and AI advice retrieval. - Enhanced API routes to include endpoints for AI advice and unlock functionality for non-members. - Improved database schema with new tables for AI advice and unlock records. - Expanded documentation to cover new AI features and Redis caching implementation.
166 lines
4.3 KiB
Go
Executable File
166 lines
4.3 KiB
Go
Executable File
package config
|
|
|
|
import (
|
|
"log"
|
|
"os"
|
|
"strconv"
|
|
"time"
|
|
|
|
"github.com/joho/godotenv"
|
|
)
|
|
|
|
type Config struct {
|
|
Server ServerConfig
|
|
Database DatabaseConfig
|
|
JWT JWTConfig
|
|
ShortVideo ShortVideoConfig
|
|
AI AIConfig
|
|
Admin AdminConfig
|
|
Qiniu QiniuConfig
|
|
WeChatOA WeChatOfficialConfig
|
|
Redis RedisConfig
|
|
}
|
|
|
|
type ServerConfig struct {
|
|
Port string
|
|
Mode string
|
|
}
|
|
|
|
type DatabaseConfig struct {
|
|
Host string
|
|
Port string
|
|
User string
|
|
Password string
|
|
DBName string
|
|
}
|
|
|
|
type JWTConfig struct {
|
|
Secret string
|
|
Expire int
|
|
}
|
|
|
|
type ShortVideoConfig struct {
|
|
APIKey string
|
|
FreeDailyQuota int
|
|
RequestTimeout time.Duration
|
|
}
|
|
|
|
// AIConfig 用于“AI 建议/问答”等能力的通用配置(OpenAI-compatible)。
|
|
type AIConfig struct {
|
|
BaseURL string
|
|
APIKey string
|
|
Model string
|
|
RequestTimeout time.Duration
|
|
}
|
|
|
|
// AdminConfig 用于简单的后台/运维接口鉴权(如生成兑换码)。
|
|
type AdminConfig struct {
|
|
Token string
|
|
}
|
|
|
|
// QiniuConfig 用于七牛云(Kodo)直传相关配置。
|
|
// 前端通常会向后端请求 upload token,然后直传文件到七牛。
|
|
type QiniuConfig struct {
|
|
AccessKey string
|
|
SecretKey string
|
|
Bucket string
|
|
UploadURL string
|
|
CDNDomain string
|
|
KeyPrefix string
|
|
TokenExpireSeconds int
|
|
}
|
|
|
|
// WeChatOfficialConfig 用于微信公众号网页授权(OAuth2)相关接口。
|
|
type WeChatOfficialConfig struct {
|
|
AppID string
|
|
AppSecret string
|
|
RequestTimeout time.Duration
|
|
}
|
|
|
|
// RedisConfig 用于可选的 Redis 缓存(例如缓存 session_key -> user,减少 DB 查询)。
|
|
type RedisConfig struct {
|
|
Addr string
|
|
Password string
|
|
DB int
|
|
KeyPrefix string
|
|
SessionTTLSeconds int
|
|
}
|
|
|
|
var AppConfig *Config
|
|
|
|
func LoadConfig() {
|
|
// 加载 .env 文件
|
|
if err := godotenv.Load(); err != nil {
|
|
log.Println("未找到 .env 文件,使用环境变量")
|
|
}
|
|
|
|
AppConfig = &Config{
|
|
Server: ServerConfig{
|
|
Port: getEnv("SERVER_PORT", "8080"),
|
|
Mode: getEnv("GIN_MODE", "debug"),
|
|
},
|
|
Database: DatabaseConfig{
|
|
Host: getEnv("DB_HOST", "localhost"),
|
|
Port: getEnv("DB_PORT", "3306"),
|
|
User: getEnv("DB_USER", "root"),
|
|
Password: getEnv("DB_PASSWORD", ""),
|
|
DBName: getEnv("DB_NAME", "wx_service"),
|
|
},
|
|
JWT: JWTConfig{
|
|
Secret: getEnv("JWT_SECRET", "your-secret-key"),
|
|
Expire: 86400, // 24小时
|
|
},
|
|
ShortVideo: ShortVideoConfig{
|
|
APIKey: getEnv("SHORT_VIDEO_API_KEY", ""),
|
|
FreeDailyQuota: getEnvAsInt("SHORT_VIDEO_FREE_QUOTA", 20),
|
|
RequestTimeout: time.Duration(getEnvAsInt("SHORT_VIDEO_TIMEOUT_SECONDS", 5)) * time.Second,
|
|
},
|
|
AI: AIConfig{
|
|
BaseURL: getEnv("AI_BASE_URL", "https://api.openai.com/v1"),
|
|
APIKey: getEnv("AI_API_KEY", ""),
|
|
Model: getEnv("AI_MODEL", "gpt-4o-mini"),
|
|
RequestTimeout: time.Duration(getEnvAsInt("AI_TIMEOUT_SECONDS", 15)) * time.Second,
|
|
},
|
|
Admin: AdminConfig{
|
|
Token: getEnv("ADMIN_API_TOKEN", ""),
|
|
},
|
|
Qiniu: QiniuConfig{
|
|
AccessKey: getEnv("QINIU_ACCESS_KEY", ""),
|
|
SecretKey: getEnv("QINIU_SECRET_KEY", ""),
|
|
Bucket: getEnv("QINIU_BUCKET", ""),
|
|
UploadURL: getEnv("QINIU_UPLOAD_URL", "https://upload.qiniup.com"),
|
|
CDNDomain: getEnv("QINIU_CDN_DOMAIN", ""),
|
|
KeyPrefix: getEnv("QINIU_KEY_PREFIX", "uploads/"),
|
|
TokenExpireSeconds: getEnvAsInt("QINIU_TOKEN_EXPIRE_SECONDS", 300),
|
|
},
|
|
WeChatOA: WeChatOfficialConfig{
|
|
AppID: getEnv("WECHAT_OA_APP_ID", ""),
|
|
AppSecret: getEnv("WECHAT_OA_APP_SECRET", ""),
|
|
RequestTimeout: time.Duration(getEnvAsInt("WECHAT_OA_TIMEOUT_SECONDS", 5)) * time.Second,
|
|
},
|
|
Redis: RedisConfig{
|
|
Addr: getEnv("REDIS_ADDR", ""),
|
|
Password: getEnv("REDIS_PASSWORD", ""),
|
|
DB: getEnvAsInt("REDIS_DB", 0),
|
|
KeyPrefix: getEnv("REDIS_KEY_PREFIX", "wx_service:"),
|
|
SessionTTLSeconds: getEnvAsInt("REDIS_SESSION_TTL_SECONDS", 86400),
|
|
},
|
|
}
|
|
}
|
|
|
|
func getEnv(key, defaultValue string) string {
|
|
if value := os.Getenv(key); value != "" {
|
|
return value
|
|
}
|
|
return defaultValue
|
|
}
|
|
|
|
func getEnvAsInt(key string, defaultValue int) int {
|
|
if value := os.Getenv(key); value != "" {
|
|
if v, err := strconv.Atoi(value); err == nil {
|
|
return v
|
|
}
|
|
}
|
|
return defaultValue
|
|
}
|