Merge pull request #121 from yokowu/feat-base-url

feat: 通过请求获取 base url, 减少配置项
This commit is contained in:
Yoko
2025-07-22 11:35:29 +08:00
committed by GitHub
10 changed files with 54 additions and 21 deletions

View File

@@ -17,8 +17,6 @@ type Config struct {
Logger *logger.Config `mapstructure:"logger"`
BaseUrl string `mapstructure:"base_url"`
Server struct {
Addr string `mapstructure:"addr"`
} `mapstructure:"server"`
@@ -81,7 +79,6 @@ func Init() (*Config, error) {
v.SetDefault("debug", false)
v.SetDefault("logger.level", "info")
v.SetDefault("base_url", "")
v.SetDefault("server.addr", ":8888")
v.SetDefault("admin.user", "admin")
v.SetDefault("admin.password", "")

View File

@@ -2618,7 +2618,7 @@
},
"/v1/report": {
"post": {
"description": "报告",
"description": "报告支持多种操作accept接受补全、suggest建议、reject拒绝补全并记录用户输入、file_written文件写入",
"consumes": [
"application/json"
],
@@ -2748,12 +2748,14 @@
"enum": [
"accept",
"suggest",
"file_written"
"file_written",
"reject"
],
"x-enum-varnames": [
"ReportActionAccept",
"ReportActionSuggest",
"ReportActionFileWritten"
"ReportActionFileWritten",
"ReportActionReject"
]
},
"consts.UserPlatform": {
@@ -3807,13 +3809,25 @@
"description": "内容",
"type": "string"
},
"cursor_position": {
"description": "光标位置用于reject action",
"type": "integer"
},
"id": {
"description": "task_id or resp_id",
"type": "string"
},
"source_code": {
"description": "当前文件的原文用于reject action",
"type": "string"
},
"tool": {
"description": "工具",
"type": "string"
},
"user_input": {
"description": "用户输入的新文本用于reject action",
"type": "string"
}
}
},

View File

@@ -37,6 +37,7 @@ type OAuthSignUpOrInReq struct {
SessionID string `json:"session_id" query:"session_id"` // 会话ID
RedirectURL string `json:"redirect_url" query:"redirect_url"` // 登录成功后跳转的 URL
InviteCode string `json:"inviate_code" query:"inviate_code"` // 邀请码
BaseURL string `json:"-"`
}
func (o OAuthSignUpOrInReq) OAuthKind() consts.OAuthKind {
@@ -47,9 +48,10 @@ func (o OAuthSignUpOrInReq) OAuthKind() consts.OAuthKind {
}
type OAuthCallbackReq struct {
State string `json:"state" query:"state" validate:"required"`
Code string `json:"code" query:"code" validate:"required"`
IP string `json:"-"`
State string `json:"state" query:"state" validate:"required"`
Code string `json:"code" query:"code" validate:"required"`
IP string `json:"-"`
BaseURL string `json:"-"`
}
type OAuthURLResp struct {

View File

@@ -60,8 +60,9 @@ func (m *ModelData) From(e *db.Model) *ModelData {
}
type ConfigReq struct {
Key string
Type consts.ConfigType `json:"type" query:"type"`
Type consts.ConfigType `json:"type" query:"type"`
Key string `json:"-"`
BaseURL string `json:"-"`
}
type ConfigResp struct {

View File

@@ -85,6 +85,7 @@ type VSCodeAuthInitReq struct {
OSType consts.OSType `json:"os_type"` // 操作系统类型
OSRelease consts.OSRelease `json:"os_release"` // 操作系统版本
Hostname string `json:"hostname"` // 主机名
BaseURL string `json:"-"`
}
type VSCodeAuthInitResp struct {

View File

@@ -13,6 +13,7 @@ import (
"github.com/chaitin/MonkeyCode/backend/domain"
"github.com/chaitin/MonkeyCode/backend/internal/middleware"
"github.com/chaitin/MonkeyCode/backend/internal/proxy"
"github.com/chaitin/MonkeyCode/backend/pkg/request"
)
type V1Handler struct {
@@ -75,7 +76,7 @@ func (h *V1Handler) Version(c *web.Context) error {
return c.JSON(http.StatusOK, domain.VersionInfo{
Version: v.Version,
URL: fmt.Sprintf("%s/api/v1/static/vsix/%s", h.config.BaseUrl, v.Version),
URL: fmt.Sprintf("%s/api/v1/static/vsix/%s", request.GetBaseURL(c.Request()), v.Version),
})
}
@@ -182,6 +183,7 @@ func (h *V1Handler) Embeddings(c *web.Context) error {
func (h *V1Handler) GetConfig(c *web.Context, req domain.ConfigReq) error {
key := middleware.GetApiKey(c)
req.Key = key.Key
req.BaseURL = request.GetBaseURL(c.Request())
resp, err := h.usecase.GetConfig(c.Request().Context(), &req)
if err != nil {
return err

View File

@@ -77,7 +77,7 @@ func (u *OpenAIUsecase) GetConfig(ctx context.Context, req *domain.ConfigReq) (*
cnt := bytes.NewBuffer(nil)
if err := t.Execute(cnt, map[string]string{
"apiBase": u.cfg.BaseUrl,
"apiBase": req.BaseURL,
"apikey": apiKey.Key,
"chatModel": chatModel,
"codeModel": codeModel,

View File

@@ -18,6 +18,7 @@ import (
"github.com/chaitin/MonkeyCode/backend/domain"
"github.com/chaitin/MonkeyCode/backend/errcode"
"github.com/chaitin/MonkeyCode/backend/internal/middleware"
"github.com/chaitin/MonkeyCode/backend/pkg/request"
"github.com/chaitin/MonkeyCode/backend/pkg/session"
"github.com/chaitin/MonkeyCode/backend/pkg/vsix"
)
@@ -121,6 +122,7 @@ func NewUserHandler(
}
func (h *UserHandler) VSCodeAuthInit(c *web.Context, req domain.VSCodeAuthInitReq) error {
req.BaseURL = request.GetBaseURL(c.Request())
resp, err := h.usecase.VSCodeAuthInit(c.Request().Context(), &req)
if err != nil {
return err
@@ -167,7 +169,7 @@ func (h *UserHandler) VSIXDownload(c *web.Context) error {
return err
}
cacheKey := h.generateCacheKey(v.Version, h.cfg.BaseUrl)
cacheKey := h.generateCacheKey(v.Version, request.GetBaseURL(c.Request()))
h.cacheMu.RLock()
if entry, exists := h.vsixCache[cacheKey]; exists {
@@ -186,7 +188,7 @@ func (h *UserHandler) VSIXDownload(c *web.Context) error {
h.cacheMu.RUnlock()
var buf bytes.Buffer
if err := vsix.ChangeVsixEndpoint(v.Path, "extension/package.json", h.cfg.BaseUrl, &buf); err != nil {
if err := vsix.ChangeVsixEndpoint(v.Path, "extension/package.json", request.GetBaseURL(c.Request()), &buf); err != nil {
return err
}
@@ -504,6 +506,7 @@ func (h *UserHandler) UpdateSetting(c *web.Context, req domain.UpdateSettingReq)
// @Router /api/v1/user/oauth/signup-or-in [get]
func (h *UserHandler) OAuthSignUpOrIn(ctx *web.Context, req domain.OAuthSignUpOrInReq) error {
h.logger.With("req", req).DebugContext(ctx.Request().Context(), "OAuthSignUpOrIn")
req.BaseURL = request.GetBaseURL(ctx.Request())
resp, err := h.usecase.OAuthSignUpOrIn(ctx.Request().Context(), &req)
if err != nil {
return err
@@ -523,7 +526,6 @@ func (h *UserHandler) OAuthSignUpOrIn(ctx *web.Context, req domain.OAuthSignUpOr
// @Success 200 {object} web.Resp{data=string}
// @Router /api/v1/user/oauth/callback [get]
func (h *UserHandler) OAuthCallback(ctx *web.Context, req domain.OAuthCallbackReq) error {
req.IP = ctx.RealIP()
return h.usecase.OAuthCallback(ctx, &req)
}

View File

@@ -24,6 +24,7 @@ import (
"github.com/chaitin/MonkeyCode/backend/errcode"
"github.com/chaitin/MonkeyCode/backend/pkg/cvt"
"github.com/chaitin/MonkeyCode/backend/pkg/oauth"
"github.com/chaitin/MonkeyCode/backend/pkg/request"
"github.com/chaitin/MonkeyCode/backend/pkg/session"
)
@@ -291,7 +292,7 @@ func (u *UserUsecase) VSCodeAuthInit(ctx context.Context, req *domain.VSCodeAuth
return nil, err
}
return &domain.VSCodeAuthInitResp{
AuthURL: fmt.Sprintf("%s?session_id=%s", u.cfg.BaseUrl+"/auth", i),
AuthURL: fmt.Sprintf("%s?session_id=%s", req.BaseURL+"/auth", i),
}, nil
}
@@ -422,11 +423,11 @@ func (u *UserUsecase) DeleteAdmin(ctx context.Context, id string) error {
return u.repo.DeleteAdmin(ctx, id)
}
func (u *UserUsecase) getOAuthConfig(setting *db.Setting, platform consts.UserPlatform) (*domain.OAuthConfig, error) {
func (u *UserUsecase) getOAuthConfig(baseURL string, setting *db.Setting, platform consts.UserPlatform) (*domain.OAuthConfig, error) {
cfg := domain.OAuthConfig{
Debug: u.cfg.Debug,
Platform: platform,
RedirectURI: fmt.Sprintf("%s/api/v1/user/oauth/callback", u.cfg.BaseUrl),
RedirectURI: fmt.Sprintf("%s/api/v1/user/oauth/callback", baseURL),
}
switch platform {
@@ -462,7 +463,7 @@ func (u *UserUsecase) OAuthSignUpOrIn(ctx context.Context, req *domain.OAuthSign
if err != nil {
return nil, err
}
cfg, err := u.getOAuthConfig(setting, req.Platform)
cfg, err := u.getOAuthConfig(req.BaseURL, setting, req.Platform)
if err != nil {
return nil, err
}
@@ -496,6 +497,8 @@ func (u *UserUsecase) OAuthSignUpOrIn(ctx context.Context, req *domain.OAuthSign
func (u *UserUsecase) OAuthCallback(c *web.Context, req *domain.OAuthCallbackReq) error {
ctx := c.Request().Context()
req.IP = c.RealIP()
req.BaseURL = request.GetBaseURL(c.Request())
b, err := u.redis.Get(ctx, fmt.Sprintf("oauth:state:%s", req.State)).Result()
if err != nil {
return err
@@ -553,7 +556,7 @@ func (u *UserUsecase) FetchUserInfo(ctx context.Context, req *domain.OAuthCallba
return nil, err
}
cfg, err := u.getOAuthConfig(setting, session.Platform)
cfg, err := u.getOAuthConfig(req.BaseURL, setting, session.Platform)
if err != nil {
return nil, err
}

View File

@@ -195,3 +195,14 @@ func GetHeaderMap(header string) map[string]string {
}
return headerMap
}
func GetBaseURL(req *http.Request) string {
scheme := "http"
if req.TLS != nil {
scheme = "https"
}
if proto := req.Header.Get("X-Forwarded-Proto"); proto != "" {
scheme = proto
}
return fmt.Sprintf("%s://%s", scheme, req.Host)
}