// Package config 从环境变量或 .env 加载配置(main 启动时 godotenv.Load)。 // // 与主流程的关系: // - XK_API_* / XkAPICallbackPath → 步骤 ①②④⑤ 调云端 xk-api // - HY_* → 步骤 ③ 监管报文 AES 加密与 HMAC 签名 // - FORWARD_BASE_URL → 步骤 ③ 内网 xk-hy-forward-go 入口(监管 JSON + PDF 上传双通道) // - FILE_UPLOAD_VIA_FORWARD → true 时 PDF 上传走 forward,不直连政务云 28211 // - MYSQL_DSN → 本机 hy_sync_job / hy_push_* 审计表 // - CRON_EXPR / SCHEDULE_TIME → serve 子命令定时 // - ANCHOR_OFFSET_DAYS → 未传 --date 时的默认锚定日(通常=昨日) package config import ( "os" "strconv" "strings" ) // Config 监管中转运行所需的全部配置项。 type Config struct { XkAPIBaseURL string // 云端根地址,如 https://api.xiaokang88.com XkAPIToken string // 对应云端 HY_TRANSIT_API_TOKEN,Header: X-Hy-Transit-Token HyAppKey string // 监管平台 AppKey(加密上报) HyAppSecret string // 监管平台 Secret(签名) HyAesKey string // 监管平台 AES 密钥(body 加密) ForwardBaseURL string // xk-hy-forward-go 地址,如 http://192.168.1.10:8080 ForwardSharedSecret string // 与 forward-go FORWARD_SHARED_SECRET 一致,Header X-Forward-Token FileUploadViaForward bool // true:PDF 上传经 forward /mng/file/auth/upload,不直连政务云 MySQLDSN string // 本机中转库 DSN(hy_transit_schema.sql) AnchorOffsetDays int // 锚定日 = 今天 - N 天,默认 1 XkAPICallbackPath string // 批量回调路径,默认 /api/hy/transit/batch/callback CronExpr string // serve 用,默认 0 22 * * * ScheduleTime string // HH:MM,仅当未设 CRON_EXPR 时转为 cron ChromePath string // 可选:Chrome/Edge 路径,未设则自动探测 FileUploadInsecureSkipVerify bool // 文件上传 HTTPS 跳过证书校验(政务网) LogWebAddr string // Web 控制台监听,默认 127.0.0.1:8765 LogWebAllowTest bool // 是否允许 Web 触发测试 sync } // Load 读取环境变量;未设置时使用默认值。 func Load() Config { return Config{ XkAPIBaseURL: env("XK_API_BASE_URL", "https://api.xiaokang88.com"), XkAPIToken: env("XK_API_TOKEN", ""), HyAppKey: env("HY_APP_KEY", ""), HyAppSecret: env("HY_APP_SECRET", ""), HyAesKey: env("HY_AES_KEY", ""), ForwardBaseURL: strings.TrimRight(env("FORWARD_BASE_URL", "http://127.0.0.1:8080"), "/"), ForwardSharedSecret: env("FORWARD_SHARED_SECRET", ""), FileUploadViaForward: envBool("FILE_UPLOAD_VIA_FORWARD", true), MySQLDSN: env("MYSQL_DSN", "root:password@tcp(127.0.0.1:3306)/xk_hy_transit?parseTime=true&charset=utf8mb4"), AnchorOffsetDays: envInt("ANCHOR_OFFSET_DAYS", 1), XkAPICallbackPath: env("XK_API_CALLBACK_PATH", "/api/hy/transit/batch/callback"), CronExpr: env("CRON_EXPR", "*/2 * * * *"), ScheduleTime: env("SCHEDULE_TIME", ""), ChromePath: env("CHROME_PATH", ""), FileUploadInsecureSkipVerify: envBool("FILE_UPLOAD_INSECURE_SKIP_VERIFY", true), LogWebAddr: env("LOG_WEB_ADDR", ":8765"), LogWebAllowTest: envBool("LOG_WEB_ALLOW_TEST", true), } } func envBool(key string, def bool) bool { v := strings.TrimSpace(strings.ToLower(os.Getenv(key))) if v == "" { return def } switch v { case "1", "true", "yes", "on": return true case "0", "false", "no", "off": return false default: return def } } func env(key, def string) string { if v := strings.TrimSpace(os.Getenv(key)); v != "" { return v } return def } func envInt(key string, def int) int { v := strings.TrimSpace(os.Getenv(key)) if v == "" { return def } n, err := strconv.Atoi(v) if err != nil { return def } return n }