156 lines
4.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package main
import (
"context"
"encoding/base64"
"flag"
"fmt"
"os"
"bindbox-game/configs"
"bindbox-game/internal/pkg/logger"
"bindbox-game/internal/repository/mysql"
"bindbox-game/internal/repository/mysql/dao"
"bindbox-game/internal/service/sysconfig"
)
var (
dryRun = flag.Bool("dry-run", false, "仅打印将要写入的配置,不实际写入数据库")
force = flag.Bool("force", false, "强制覆盖已存在的配置")
)
func main() {
flag.Parse()
// 初始化数据库
dbRepo, err := mysql.New()
if err != nil {
fmt.Printf("数据库连接失败: %v\n", err)
os.Exit(1)
}
// 初始化 logger (简化版)
customLogger, err := logger.NewCustomLogger(dao.Use(dbRepo.GetDbW()),
logger.WithDebugLevel(),
logger.WithOutputInConsole(),
)
if err != nil {
fmt.Printf("Logger 初始化失败: %v\n", err)
os.Exit(1)
}
ctx := context.Background()
// 创建动态配置服务
dynamicCfg := sysconfig.NewDynamicConfig(customLogger, dbRepo)
staticCfg := configs.Get()
// 定义要迁移的配置项
type configItem struct {
Key string
Value string
Remark string
}
// 读取证书文件内容并 Base64 编码
readAndEncode := func(path string) string {
if path == "" {
return ""
}
data, err := os.ReadFile(path)
if err != nil {
fmt.Printf("警告: 读取文件 %s 失败: %v\n", path, err)
return ""
}
return base64.StdEncoding.EncodeToString(data)
}
items := []configItem{
// COS 配置
{sysconfig.KeyCOSBucket, staticCfg.COS.Bucket, "COS Bucket名称"},
{sysconfig.KeyCOSRegion, staticCfg.COS.Region, "COS 地域"},
{sysconfig.KeyCOSSecretID, staticCfg.COS.SecretID, "COS SecretID (加密存储)"},
{sysconfig.KeyCOSSecretKey, staticCfg.COS.SecretKey, "COS SecretKey (加密存储)"},
{sysconfig.KeyCOSBaseURL, staticCfg.COS.BaseURL, "COS 自定义域名"},
// 微信小程序配置
{sysconfig.KeyWechatAppID, staticCfg.Wechat.AppID, "微信小程序 AppID"},
{sysconfig.KeyWechatAppSecret, staticCfg.Wechat.AppSecret, "微信小程序 AppSecret (加密存储)"},
{sysconfig.KeyWechatLotteryResultTemplateID, staticCfg.Wechat.LotteryResultTemplateID, "中奖结果订阅消息模板ID"},
// 微信支付配置
{sysconfig.KeyWechatPayMchID, staticCfg.WechatPay.MchID, "微信支付商户号"},
{sysconfig.KeyWechatPaySerialNo, staticCfg.WechatPay.SerialNo, "微信支付证书序列号"},
{sysconfig.KeyWechatPayPrivateKey, readAndEncode(staticCfg.WechatPay.PrivateKeyPath), "微信支付私钥 (Base64编码, 加密存储)"},
{sysconfig.KeyWechatPayApiV3Key, staticCfg.WechatPay.ApiV3Key, "微信支付 API v3 密钥 (加密存储)"},
{sysconfig.KeyWechatPayNotifyURL, staticCfg.WechatPay.NotifyURL, "微信支付回调地址"},
{sysconfig.KeyWechatPayPublicKeyID, staticCfg.WechatPay.PublicKeyID, "微信支付公钥ID"},
{sysconfig.KeyWechatPayPublicKey, readAndEncode(staticCfg.WechatPay.PublicKeyPath), "微信支付公钥 (Base64编码, 加密存储)"},
// 阿里云短信配置
{sysconfig.KeyAliyunSMSAccessKeyID, staticCfg.AliyunSMS.AccessKeyID, "阿里云短信 AccessKeyID"},
{sysconfig.KeyAliyunSMSAccessKeySecret, staticCfg.AliyunSMS.AccessKeySecret, "阿里云短信 AccessKeySecret (加密存储)"},
{sysconfig.KeyAliyunSMSSignName, staticCfg.AliyunSMS.SignName, "短信签名"},
{sysconfig.KeyAliyunSMSTemplateCode, staticCfg.AliyunSMS.TemplateCode, "短信模板Code"},
}
fmt.Println("========== 配置迁移工具 ==========")
fmt.Printf("环境: %s\n", configs.ProjectName)
fmt.Printf("Dry Run: %v\n", *dryRun)
fmt.Printf("Force: %v\n", *force)
fmt.Println()
successCount := 0
skipCount := 0
failCount := 0
for _, item := range items {
if item.Value == "" {
fmt.Printf("[跳过] %s: 值为空\n", item.Key)
skipCount++
continue
}
// 检查是否已存在
existing := dynamicCfg.Get(ctx, item.Key)
if existing != "" && !*force {
fmt.Printf("[跳过] %s: 已存在 (使用 -force 覆盖)\n", item.Key)
skipCount++
continue
}
// 脱敏显示
displayValue := item.Value
if sysconfig.IsSensitiveKey(item.Key) {
if len(displayValue) > 8 {
displayValue = displayValue[:4] + "****" + displayValue[len(displayValue)-4:]
} else {
displayValue = "****"
}
} else if len(displayValue) > 50 {
displayValue = displayValue[:50] + "..."
}
if *dryRun {
fmt.Printf("[预览] %s = %s\n", item.Key, displayValue)
successCount++
} else {
if err := dynamicCfg.Set(ctx, item.Key, item.Value, item.Remark); err != nil {
fmt.Printf("[失败] %s: %v\n", item.Key, err)
failCount++
} else {
fmt.Printf("[成功] %s = %s\n", item.Key, displayValue)
successCount++
}
}
}
fmt.Println()
fmt.Printf("========== 迁移结果 ==========\n")
fmt.Printf("成功: %d, 跳过: %d, 失败: %d\n", successCount, skipCount, failCount)
if *dryRun {
fmt.Println("\n这只是预览使用不带 -dry-run 参数执行实际迁移")
}
}