155 lines
6.3 KiB
Go
155 lines
6.3 KiB
Go
package handler
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"gpt-plus/internal/db"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
type configGroup struct {
|
|
Group string `json:"group"`
|
|
Items []db.SystemConfig `json:"items"`
|
|
}
|
|
|
|
func GetConfig(c *gin.Context) {
|
|
var configs []db.SystemConfig
|
|
if err := db.GetDB().Order("\"group\", key").Find(&configs).Error; err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
// Mask password fields
|
|
for i := range configs {
|
|
if configs[i].Type == "password" && configs[i].Value != "" {
|
|
configs[i].Value = "••••••••"
|
|
}
|
|
}
|
|
|
|
groups := make(map[string][]db.SystemConfig)
|
|
for _, cfg := range configs {
|
|
groups[cfg.Group] = append(groups[cfg.Group], cfg)
|
|
}
|
|
c.JSON(http.StatusOK, gin.H{"groups": groups})
|
|
}
|
|
|
|
type updateConfigRequest struct {
|
|
Items []struct {
|
|
Key string `json:"key" binding:"required"`
|
|
Value string `json:"value"`
|
|
} `json:"items" binding:"required"`
|
|
}
|
|
|
|
func UpdateConfig(c *gin.Context) {
|
|
var req updateConfigRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
|
|
tx := db.GetDB().Begin()
|
|
for _, item := range req.Items {
|
|
// Skip masked password values
|
|
if item.Value == "••••••••" {
|
|
continue
|
|
}
|
|
|
|
var existing db.SystemConfig
|
|
if err := tx.Where("key = ?", item.Key).First(&existing).Error; err != nil {
|
|
tx.Rollback()
|
|
c.JSON(http.StatusNotFound, gin.H{"error": "配置项不存在: " + item.Key})
|
|
return
|
|
}
|
|
|
|
value := item.Value
|
|
if existing.Type == "password" && value != "" {
|
|
encrypted, err := db.Encrypt(value)
|
|
if err != nil {
|
|
tx.Rollback()
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "加密失败"})
|
|
return
|
|
}
|
|
value = encrypted
|
|
}
|
|
|
|
if err := tx.Model(&existing).Update("value", value).Error; err != nil {
|
|
tx.Rollback()
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
}
|
|
tx.Commit()
|
|
c.JSON(http.StatusOK, gin.H{"message": "配置已更新"})
|
|
}
|
|
|
|
func SeedDefaultConfigs() {
|
|
defaults := []db.SystemConfig{
|
|
// Proxy group
|
|
{Key: "proxy.mode", Value: "b2proxy", Group: "proxy", Label: "代理模式", Type: "string"},
|
|
{Key: "proxy.url", Value: "", Group: "proxy", Label: "代理地址", Type: "string"},
|
|
{Key: "proxy.b2proxy.enabled", Value: "true", Group: "proxy", Label: "启用 B2Proxy", Type: "bool"},
|
|
{Key: "proxy.b2proxy.api_base", Value: "http://global.rrp.b2proxy.com:8089", Group: "proxy", Label: "B2Proxy API 地址", Type: "string"},
|
|
{Key: "proxy.b2proxy.zone", Value: "custom", Group: "proxy", Label: "B2Proxy 区域", Type: "string"},
|
|
{Key: "proxy.b2proxy.proto", Value: "socks5", Group: "proxy", Label: "B2Proxy 协议", Type: "string"},
|
|
{Key: "proxy.b2proxy.sess_time", Value: "5", Group: "proxy", Label: "会话时长(分钟)", Type: "int"},
|
|
|
|
// Email group
|
|
{Key: "email.gateway.base_url", Value: "https://regmail.zhengmi.org", Group: "email", Label: "邮箱网关地址", Type: "string"},
|
|
{Key: "email.gateway.api_key", Value: "Admin2026.", Group: "email", Label: "邮箱网关 API Key", Type: "password"},
|
|
{Key: "email.gateway.provider", Value: "mail", Group: "email", Label: "邮箱网关 Provider", Type: "string"},
|
|
|
|
// Card group
|
|
{Key: "card.max_binds", Value: "0", Group: "card", Label: "单卡最大绑定次数(0=无限)", Type: "int"},
|
|
{Key: "card.default_name", Value: "Anna Hoover", Group: "card", Label: "默认持卡人姓名", Type: "string"},
|
|
{Key: "card.default_country", Value: "US", Group: "card", Label: "默认国家", Type: "string"},
|
|
{Key: "card.default_currency", Value: "USD", Group: "card", Label: "默认货币", Type: "string"},
|
|
{Key: "card.default_address", Value: "1208 Oakdale Street", Group: "card", Label: "默认地址", Type: "string"},
|
|
{Key: "card.default_city", Value: "Jonesboro", Group: "card", Label: "默认城市", Type: "string"},
|
|
{Key: "card.default_state", Value: "AR", Group: "card", Label: "默认州/省", Type: "string"},
|
|
{Key: "card.default_postal_code", Value: "72401", Group: "card", Label: "默认邮编", Type: "string"},
|
|
{Key: "card.api_base_url", Value: "https://yyl.ncet.top", Group: "card", Label: "开卡 API 地址", Type: "string"},
|
|
{Key: "card.api_key", Value: "", Group: "card", Label: "开卡 API 密钥", Type: "password"},
|
|
|
|
// Stripe group
|
|
{Key: "stripe.build_hash", Value: "ede17ac9fd", Group: "stripe", Label: "Build Hash", Type: "string"},
|
|
{Key: "stripe.tag_version", Value: "4.5.43", Group: "stripe", Label: "Tag Version", Type: "string"},
|
|
{Key: "stripe.fingerprint_dir", Value: "./fingerprints", Group: "stripe", Label: "指纹目录", Type: "string"},
|
|
|
|
// Captcha group
|
|
{Key: "captcha.provider", Value: "hcaptchasolver", Group: "captcha", Label: "验证码提供商", Type: "string"},
|
|
{Key: "captcha.api_key", Value: "Kenzx_4ba2535aaf33bd1238345f795a085853ace94e54ade70a2a", Group: "captcha", Label: "验证码 API Key", Type: "password"},
|
|
{Key: "captcha.proxy", Value: "", Group: "captcha", Label: "验证码代理", Type: "string"},
|
|
|
|
// Account group
|
|
{Key: "account.password_length", Value: "16", Group: "account", Label: "密码长度", Type: "int"},
|
|
{Key: "account.locale", Value: "en-GB", Group: "account", Label: "区域设置", Type: "string"},
|
|
|
|
// Team group
|
|
{Key: "team.enabled", Value: "true", Group: "team", Label: "启用 Team", Type: "bool"},
|
|
{Key: "team.workspace_prefix", Value: "Team", Group: "team", Label: "工作区前缀", Type: "string"},
|
|
{Key: "team.seat_quantity", Value: "5", Group: "team", Label: "座位数", Type: "int"},
|
|
{Key: "team.coupon", Value: "team-1-month-free", Group: "team", Label: "优惠券", Type: "string"},
|
|
{Key: "team.invite_count", Value: "0", Group: "team", Label: "邀请人数", Type: "int"},
|
|
|
|
// CPA (CLI Proxy API) group
|
|
{Key: "cpa.base_url", Value: "http://127.0.0.1:8317", Group: "cpa", Label: "CPA 地址", Type: "string"},
|
|
{Key: "cpa.management_key", Value: "gptplus2026", Group: "cpa", Label: "Management Key", Type: "password"},
|
|
}
|
|
|
|
d := db.GetDB()
|
|
for _, cfg := range defaults {
|
|
var existing db.SystemConfig
|
|
res := d.Where("key = ?", cfg.Key).First(&existing)
|
|
if res.Error != nil {
|
|
d.Create(&cfg)
|
|
} else if existing.Value == "" && cfg.Value != "" {
|
|
d.Model(&existing).Updates(map[string]interface{}{
|
|
"value": cfg.Value,
|
|
"label": cfg.Label,
|
|
"type": cfg.Type,
|
|
})
|
|
}
|
|
}
|
|
}
|