mirror of
https://github.com/yangjian102621/geekai.git
synced 2026-09-17 02:37:14 +00:00
feat: 迁移 geekai-plus v4.3.1 到开源版
- 同步 Plus v4.3.1 功能源并移除商业 License 闭环 - 更新开源镜像命名、Docker 部署版本和 geekai 数据库配置 - 补充前端 ESLint 检查配置并修复存量解析与模板问题 - 保留 JWT、管理员权限、API Key 和 OAuth 等正常鉴权机制
This commit is contained in:
@@ -9,6 +9,8 @@ package admin
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"geekai/core"
|
||||
"geekai/core/middleware"
|
||||
"geekai/core/types"
|
||||
@@ -31,6 +33,7 @@ type ConfigHandler struct {
|
||||
alipayService *payment.AlipayService
|
||||
wxpayService *payment.WxPayService
|
||||
epayService *payment.EPayService
|
||||
stripeService *payment.StripeService
|
||||
smsManager *sms.SmsManager
|
||||
uploaderManager *oss.UploaderManager
|
||||
smtpService *service.SmtpService
|
||||
@@ -46,6 +49,7 @@ func NewConfigHandler(
|
||||
alipayService *payment.AlipayService,
|
||||
wxpayService *payment.WxPayService,
|
||||
epayService *payment.EPayService,
|
||||
stripeService *payment.StripeService,
|
||||
smsManager *sms.SmsManager,
|
||||
uploaderManager *oss.UploaderManager,
|
||||
smtpService *service.SmtpService,
|
||||
@@ -59,6 +63,7 @@ func NewConfigHandler(
|
||||
alipayService: alipayService,
|
||||
wxpayService: wxpayService,
|
||||
epayService: epayService,
|
||||
stripeService: stripeService,
|
||||
smsManager: smsManager,
|
||||
uploaderManager: uploaderManager,
|
||||
smtpService: smtpService,
|
||||
@@ -89,6 +94,9 @@ func (h *ConfigHandler) RegisterRoutes() {
|
||||
rg.POST("update/smtp", h.UpdateStmp)
|
||||
rg.GET("get", h.Get)
|
||||
rg.POST("update/wx_gzh", h.UpdateWxGzh)
|
||||
rg.POST("update/wx_gzh_menu", h.UpdateWxGzhMenu)
|
||||
rg.POST("wx_gzh/menu/publish", h.PublishWxGzhMenu)
|
||||
rg.GET("wx_gzh/menu/query", h.QueryWxGzhMenu)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -282,6 +290,9 @@ func (h *ConfigHandler) UpdatePayment(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
}
|
||||
if data.Stripe.Enabled {
|
||||
h.stripeService.UpdateConfig(&data.Stripe)
|
||||
}
|
||||
|
||||
h.sysConfig.Payment = data
|
||||
resp.SUCCESS(c, data)
|
||||
@@ -335,6 +346,10 @@ func (h *ConfigHandler) UpdateStmp(c *gin.Context) {
|
||||
resp.ERROR(c, types.InvalidArgs)
|
||||
return
|
||||
}
|
||||
if data.Host == "" || data.Port <= 0 {
|
||||
resp.ERROR(c, "邮件服务器地址和端口不能为空")
|
||||
return
|
||||
}
|
||||
|
||||
err := h.Update(types.ConfigKeySmtp, data)
|
||||
if err != nil {
|
||||
@@ -422,3 +437,103 @@ func (h *ConfigHandler) UpdateWxGzh(c *gin.Context) {
|
||||
h.sysConfig.WxGzh = data
|
||||
resp.SUCCESS(c, data)
|
||||
}
|
||||
|
||||
// UpdateWxGzhMenu 保存公众号自定义菜单草稿(不调用微信接口)。
|
||||
func (h *ConfigHandler) UpdateWxGzhMenu(c *gin.Context) {
|
||||
var data types.WxGzhMenuConfig
|
||||
if err := c.ShouldBindJSON(&data); err != nil {
|
||||
resp.ERROR(c, types.InvalidArgs)
|
||||
return
|
||||
}
|
||||
if data.Button == nil {
|
||||
data.Button = []types.WxGzhMenuButton{}
|
||||
}
|
||||
if err := h.Update(types.ConfigKeyWxGzhMenu, data); err != nil {
|
||||
resp.ERROR(c, err.Error())
|
||||
return
|
||||
}
|
||||
resp.SUCCESS(c, data)
|
||||
}
|
||||
|
||||
func (h *ConfigHandler) loadWxGzhCredentials() (appID, secret string, err error) {
|
||||
var row model.Config
|
||||
if err = h.DB.Where("name", types.ConfigKeyWxGzh).First(&row).Error; err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
var wx types.WxGzhConfig
|
||||
if err = utils.JsonDecode(row.Value, &wx); err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
return strings.TrimSpace(wx.AppId), strings.TrimSpace(wx.Secret), nil
|
||||
}
|
||||
|
||||
// PublishWxGzhMenu 将草稿菜单同步到微信公众平台(menu/create)。
|
||||
func (h *ConfigHandler) PublishWxGzhMenu(c *gin.Context) {
|
||||
appID, secret, err := h.loadWxGzhCredentials()
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
resp.ERROR(c, "请先配置微信公众号 AppID 与 AppSecret")
|
||||
return
|
||||
}
|
||||
resp.ERROR(c, err.Error())
|
||||
return
|
||||
}
|
||||
if appID == "" || secret == "" {
|
||||
resp.ERROR(c, "请先配置微信公众号 AppID 与 AppSecret")
|
||||
return
|
||||
}
|
||||
|
||||
var menu types.WxGzhMenuConfig
|
||||
var menuRow model.Config
|
||||
if err := h.DB.Where("name", types.ConfigKeyWxGzhMenu).First(&menuRow).Error; err != nil {
|
||||
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
resp.ERROR(c, err.Error())
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if err := utils.JsonDecode(menuRow.Value, &menu); err != nil {
|
||||
resp.ERROR(c, err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
if menu.Button == nil {
|
||||
menu.Button = []types.WxGzhMenuButton{}
|
||||
}
|
||||
|
||||
if err := h.wxGzhService.PublishCustomMenu(c.Request.Context(), appID, secret, menu); err != nil {
|
||||
resp.ERROR(c, err.Error())
|
||||
return
|
||||
}
|
||||
resp.SUCCESS(c, gin.H{"message": "已同步到微信"})
|
||||
}
|
||||
|
||||
// QueryWxGzhMenu 从微信拉取当前菜单并写入草稿 wx_gzh_menu。
|
||||
func (h *ConfigHandler) QueryWxGzhMenu(c *gin.Context) {
|
||||
appID, secret, err := h.loadWxGzhCredentials()
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
resp.ERROR(c, "请先配置微信公众号 AppID 与 AppSecret")
|
||||
return
|
||||
}
|
||||
resp.ERROR(c, err.Error())
|
||||
return
|
||||
}
|
||||
if appID == "" || secret == "" {
|
||||
resp.ERROR(c, "请先配置微信公众号 AppID 与 AppSecret")
|
||||
return
|
||||
}
|
||||
|
||||
menuCfg, err := h.wxGzhService.GetCustomMenuFromWechat(c.Request.Context(), appID, secret)
|
||||
if err != nil {
|
||||
resp.ERROR(c, err.Error())
|
||||
return
|
||||
}
|
||||
if menuCfg.Button == nil {
|
||||
menuCfg.Button = []types.WxGzhMenuButton{}
|
||||
}
|
||||
if err := h.Update(types.ConfigKeyWxGzhMenu, menuCfg); err != nil {
|
||||
resp.ERROR(c, err.Error())
|
||||
return
|
||||
}
|
||||
resp.SUCCESS(c, menuCfg)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user