124 lines
5.1 KiB
Go
124 lines
5.1 KiB
Go
// Package config 使用仓库统一的 BSM 配置加载与校验方式。
|
|
package config
|
|
|
|
import (
|
|
"net"
|
|
"net/url"
|
|
"strings"
|
|
|
|
"git.apinb.com/bsm-sdk/core/conf"
|
|
)
|
|
|
|
// Spec 是 Platform API 的运行配置。
|
|
var Spec SrvConfig
|
|
|
|
// GlobalConfig 保存多个管理端共用的运行参数。
|
|
type GlobalConfig struct {
|
|
UserRegisterURL string `yaml:"UserRegisterURL"`
|
|
ManualRechargeMaxAmount int64 `yaml:"ManualRechargeMaxAmount"`
|
|
MockVerificationEnabled bool `yaml:"MockVerificationEnabled"`
|
|
MockVerificationCode string `yaml:"MockVerificationCode"`
|
|
VerificationTTLSeconds int `yaml:"VerificationTTLSeconds"`
|
|
VerificationSendIntervalSeconds int `yaml:"VerificationSendIntervalSeconds"`
|
|
MockPaymentEnabled bool `yaml:"MockPaymentEnabled"`
|
|
DeliveryArrivalRadiusMeters float64 `yaml:"DeliveryArrivalRadiusMeters"`
|
|
UploadVideoMaxSize int64 `yaml:"UploadVideoMaxSize"`
|
|
FieldEncryptionKey string `yaml:"FieldEncryptionKey"`
|
|
}
|
|
|
|
// WalletConfig 是平台既有钱包逻辑的内部兼容视图,值由 Global 注入。
|
|
type WalletConfig struct {
|
|
ManualRechargeMaxAmount int64 `yaml:"-"`
|
|
}
|
|
|
|
// AlipayConfig 保存支付宝证书模式商户配置。私钥和证书只允许服务端读取。
|
|
type AlipayConfig struct {
|
|
Enabled bool `yaml:"Enabled"`
|
|
Production bool `yaml:"Production"`
|
|
AppID string `yaml:"AppID"`
|
|
PrivateKeyPath string `yaml:"PrivateKeyPath"`
|
|
AppPublicCertPath string `yaml:"AppPublicCertPath"`
|
|
AlipayPublicCertPath string `yaml:"AlipayPublicCertPath"`
|
|
AlipayRootCertPath string `yaml:"AlipayRootCertPath"`
|
|
NotifyURL string `yaml:"NotifyURL"`
|
|
ReturnURL string `yaml:"ReturnURL"`
|
|
}
|
|
|
|
// WechatPayConfig 保存微信支付 API v3 平台单商户配置。
|
|
type WechatPayConfig struct {
|
|
Enabled bool `yaml:"Enabled"`
|
|
MerchantID string `yaml:"MerchantID"`
|
|
MerchantCertificateSerial string `yaml:"MerchantCertificateSerial"`
|
|
MerchantPrivateKeyPath string `yaml:"MerchantPrivateKeyPath"`
|
|
APIv3Key string `yaml:"APIv3Key"`
|
|
AppAppID string `yaml:"AppAppID"`
|
|
OfficialAccountAppID string `yaml:"OfficialAccountAppID"`
|
|
MiniProgramAppID string `yaml:"MiniProgramAppID"`
|
|
NotifyURL string `yaml:"NotifyURL"`
|
|
}
|
|
|
|
// PaymentConfig 保存统一支付、退款和 Worker 内部调用参数。
|
|
type PaymentConfig struct {
|
|
ExpireMinutes int `yaml:"ExpireMinutes"`
|
|
RefundWindowDays int `yaml:"RefundWindowDays"`
|
|
InternalServiceToken string `yaml:"InternalServiceToken"`
|
|
Alipay AlipayConfig `yaml:"Alipay"`
|
|
Wechat WechatPayConfig `yaml:"Wechat"`
|
|
}
|
|
|
|
// IoTConfig 保存 API 与 IoT 链路间的内部认证配置。
|
|
type IoTConfig struct {
|
|
InternalServiceToken string `yaml:"InternalServiceToken"`
|
|
}
|
|
|
|
// SrvConfig 与仓库现有进程的配置结构保持一致。
|
|
type SrvConfig struct {
|
|
conf.Base `yaml:",inline"`
|
|
Databases *conf.DBConf `yaml:"Databases"`
|
|
Rpc map[string]conf.RpcConf `yaml:"Rpc"`
|
|
Apm *conf.ApmConf `yaml:"APM"`
|
|
Global GlobalConfig `yaml:"Global"`
|
|
Wallet WalletConfig `yaml:"-"`
|
|
Payment PaymentConfig `yaml:"Payment"`
|
|
IoT IoTConfig `yaml:"IoT"`
|
|
}
|
|
|
|
// New 初始化 BSM 配置并校验服务监听地址。
|
|
func New(srvKey string) {
|
|
conf.New(srvKey, &Spec)
|
|
Spec.Port = conf.CheckPort(Spec.Port)
|
|
Spec.BindIP = conf.CheckIP(Spec.BindIP)
|
|
Spec.Addr = net.JoinHostPort(Spec.BindIP, Spec.Port)
|
|
conf.NotNil(Spec.Service, Spec.Cache)
|
|
if Spec.Databases == nil || len(Spec.Databases.Source) == 0 {
|
|
panic("Databases configuration is required")
|
|
}
|
|
if Spec.Global.ManualRechargeMaxAmount <= 0 {
|
|
panic("Global.ManualRechargeMaxAmount must be greater than zero")
|
|
}
|
|
if Spec.Global.VerificationTTLSeconds <= 0 || Spec.Global.VerificationSendIntervalSeconds <= 0 {
|
|
panic("Global verification timeouts must be greater than zero")
|
|
}
|
|
if Spec.Global.MockVerificationEnabled && len(Spec.Global.MockVerificationCode) < 4 {
|
|
panic("Global.MockVerificationCode must contain at least four characters")
|
|
}
|
|
if Spec.Global.DeliveryArrivalRadiusMeters <= 0 || Spec.Global.UploadVideoMaxSize <= 0 {
|
|
panic("Global delivery radius and upload video size must be greater than zero")
|
|
}
|
|
if len(strings.TrimSpace(Spec.Global.FieldEncryptionKey)) < 32 {
|
|
panic("Global.FieldEncryptionKey must contain at least 32 characters")
|
|
}
|
|
Spec.Wallet.ManualRechargeMaxAmount = Spec.Global.ManualRechargeMaxAmount
|
|
if Spec.Payment.ExpireMinutes <= 0 || Spec.Payment.RefundWindowDays <= 0 {
|
|
panic("Payment expiration and refund window must be greater than zero")
|
|
}
|
|
if len(strings.TrimSpace(Spec.IoT.InternalServiceToken)) < 16 {
|
|
panic("IoT internal token is required")
|
|
}
|
|
registerURL, err := url.ParseRequestURI(Spec.Global.UserRegisterURL)
|
|
if err != nil || (registerURL.Scheme != "http" && registerURL.Scheme != "https") || registerURL.Host == "" {
|
|
panic("Global.UserRegisterURL must be a valid HTTP or HTTPS URL")
|
|
}
|
|
conf.PrintInfo(Spec.Addr)
|
|
}
|