From 204f2ae0c6dc5765e493deecdd13d33ee554b53e Mon Sep 17 00:00:00 2001 From: Bibo Hao Date: Tue, 6 Aug 2024 23:54:40 +0800 Subject: [PATCH] feat: allow baseUrl --- common/embed-file-system.go | 4 ++- router/api.go | 2 +- router/dashboard.go | 2 +- router/main.go | 12 +++++-- router/relay.go | 2 +- router/web.go | 16 +++++---- web/build.sh | 1 + web/default/package.json | 1 + web/default/public/index.html | 2 +- web/default/src/components/Header.js | 13 +++---- web/default/src/components/LoginForm.js | 17 ++++----- .../src/components/PasswordResetConfirm.js | 35 ++++++++++--------- .../src/components/PasswordResetForm.js | 3 +- web/default/src/components/RegisterForm.js | 3 +- web/default/src/config.js | 1 + web/default/src/helpers/api.js | 5 ++- web/default/src/index.js | 3 +- 17 files changed, 69 insertions(+), 53 deletions(-) create mode 100644 web/default/src/config.js diff --git a/common/embed-file-system.go b/common/embed-file-system.go index 7c0e4b4e30..021130fc75 100644 --- a/common/embed-file-system.go +++ b/common/embed-file-system.go @@ -5,6 +5,7 @@ import ( "github.com/gin-contrib/static" "io/fs" "net/http" + "strings" ) // Credit: https://github.com/gin-contrib/static/issues/19 @@ -14,7 +15,8 @@ type embedFileSystem struct { } func (e embedFileSystem) Exists(prefix string, path string) bool { - _, err := e.Open(path) + relPath := strings.TrimPrefix(path, prefix) + _, err := e.Open(relPath) return err == nil } diff --git a/router/api.go b/router/api.go index d2ada4ebda..af025b3922 100644 --- a/router/api.go +++ b/router/api.go @@ -9,7 +9,7 @@ import ( "github.com/gin-gonic/gin" ) -func SetApiRouter(router *gin.Engine) { +func SetApiRouter(router *gin.RouterGroup) { apiRouter := router.Group("/api") apiRouter.Use(gzip.Gzip(gzip.DefaultCompression)) apiRouter.Use(middleware.GlobalAPIRateLimit()) diff --git a/router/dashboard.go b/router/dashboard.go index 5952d698ae..d002bfe262 100644 --- a/router/dashboard.go +++ b/router/dashboard.go @@ -7,7 +7,7 @@ import ( "github.com/songquanpeng/one-api/middleware" ) -func SetDashboardRouter(router *gin.Engine) { +func SetDashboardRouter(router *gin.RouterGroup) { apiRouter := router.Group("/") apiRouter.Use(middleware.CORS()) apiRouter.Use(gzip.Gzip(gzip.DefaultCompression)) diff --git a/router/main.go b/router/main.go index 39d8c04f06..c67aa95bb2 100644 --- a/router/main.go +++ b/router/main.go @@ -11,7 +11,13 @@ import ( "strings" ) -func SetRouter(router *gin.Engine, buildFS embed.FS) { +func SetRouter(engine *gin.Engine, buildFS embed.FS) { + var baseUrl = os.Getenv("BASE_URL") + if baseUrl == "" { + baseUrl = "/" + } + router := engine.Group(baseUrl) + SetApiRouter(router) SetDashboardRouter(router) SetRelayRouter(router) @@ -21,10 +27,10 @@ func SetRouter(router *gin.Engine, buildFS embed.FS) { logger.SysLog("FRONTEND_BASE_URL is ignored on master node") } if frontendBaseUrl == "" { - SetWebRouter(router, buildFS) + SetWebRouter(engine, baseUrl, buildFS) } else { frontendBaseUrl = strings.TrimSuffix(frontendBaseUrl, "/") - router.NoRoute(func(c *gin.Context) { + engine.NoRoute(func(c *gin.Context) { c.Redirect(http.StatusMovedPermanently, fmt.Sprintf("%s%s", frontendBaseUrl, c.Request.RequestURI)) }) } diff --git a/router/relay.go b/router/relay.go index 094ea5fb51..bbef786dda 100644 --- a/router/relay.go +++ b/router/relay.go @@ -7,7 +7,7 @@ import ( "github.com/gin-gonic/gin" ) -func SetRelayRouter(router *gin.Engine) { +func SetRelayRouter(router *gin.RouterGroup) { router.Use(middleware.CORS()) // https://platform.openai.com/docs/api-reference/introduction modelsRouter := router.Group("/v1/models") diff --git a/router/web.go b/router/web.go index 3c9b4643a5..94cd75e5a7 100644 --- a/router/web.go +++ b/router/web.go @@ -14,13 +14,15 @@ import ( "strings" ) -func SetWebRouter(router *gin.Engine, buildFS embed.FS) { - indexPageData, _ := buildFS.ReadFile(fmt.Sprintf("web/build/%s/index.html", config.Theme)) - router.Use(gzip.Gzip(gzip.DefaultCompression)) - router.Use(middleware.GlobalWebRateLimit()) - router.Use(middleware.Cache()) - router.Use(static.Serve("/", common.EmbedFolder(buildFS, fmt.Sprintf("web/build/%s", config.Theme)))) - router.NoRoute(func(c *gin.Context) { +func SetWebRouter(engine *gin.Engine, baseUrl string, buildFS embed.FS) { + basePath := fmt.Sprintf("web/build/%s", config.Theme) + indexPageData, _ := buildFS.ReadFile(fmt.Sprintf("%s/index.html", basePath)) + engine.Use(gzip.Gzip(gzip.DefaultCompression)) + engine.Use(middleware.GlobalWebRateLimit()) + engine.Use(middleware.Cache()) + engine.Use(static.Serve(baseUrl, common.EmbedFolder(buildFS, basePath))) + + engine.NoRoute(func(c *gin.Context) { if strings.HasPrefix(c.Request.RequestURI, "/v1") || strings.HasPrefix(c.Request.RequestURI, "/api") { controller.RelayNotFound(c) return diff --git a/web/build.sh b/web/build.sh index b59babe4fa..b8b650e57e 100644 --- a/web/build.sh +++ b/web/build.sh @@ -8,6 +8,7 @@ while IFS= read -r theme; do rm -r build/$theme cd "$theme" npm install + jq ".homepage=\"${REACT_APP_BASE_URL}\"" package.json > tmp.json && mv tmp.json package.json ; DISABLE_ESLINT_PLUGIN='true' REACT_APP_VERSION=$version npm run build cd .. done < THEMES diff --git a/web/default/package.json b/web/default/package.json index ba45011f60..bd3f82b266 100644 --- a/web/default/package.json +++ b/web/default/package.json @@ -1,6 +1,7 @@ { "name": "react-template", "version": "0.1.0", + "homepage": "", "private": true, "dependencies": { "axios": "^0.27.2", diff --git a/web/default/public/index.html b/web/default/public/index.html index f22b88437b..9398a85547 100644 --- a/web/default/public/index.html +++ b/web/default/public/index.html @@ -2,7 +2,7 @@ - + { size='large' style={ showSidebar - ? { - borderBottom: 'none', - marginBottom: '0', - borderTop: 'none', - height: '51px' - } + ? { borderBottom: 'none', marginBottom: '0', borderTop: 'none', height: '51px' } : { borderTop: 'none', height: '52px' } } > logo @@ -188,7 +183,7 @@ const Header = () => { - logo + logo
{systemName}
diff --git a/web/default/src/components/LoginForm.js b/web/default/src/components/LoginForm.js index 71566ef853..3e6f0fa3d9 100644 --- a/web/default/src/components/LoginForm.js +++ b/web/default/src/components/LoginForm.js @@ -4,6 +4,7 @@ import { Link, useNavigate, useSearchParams } from 'react-router-dom'; import { UserContext } from '../context/User'; import { API, getLogo, showError, showSuccess, showWarning } from '../helpers'; import { onGitHubOAuthClicked, onLarkOAuthClicked } from './utils'; +import { BASE_URL } from '../config'; import larkIcon from '../images/lark.svg'; const LoginForm = () => { @@ -87,7 +88,7 @@ const LoginForm = () => {
- 用户登录 + 用户登录
@@ -151,13 +152,13 @@ const LoginForm = () => { )} {status.lark_client_id ? (
onLarkOAuthClicked(status.lark_client_id)} > { @@ -37,7 +38,7 @@ const PasswordResetConfirm = () => { setDisableButton(false); setCountdown(30); } - return () => clearInterval(countdownInterval); + return () => clearInterval(countdownInterval); }, [disableButton, countdown]); async function handleSubmit(e) { @@ -59,12 +60,12 @@ const PasswordResetConfirm = () => { } setLoading(false); } - + return (
- 密码重置确认 + 密码重置确认
@@ -79,19 +80,19 @@ const PasswordResetConfirm = () => { /> {newPassword && ( { - e.target.select(); - navigator.clipboard.writeText(newPassword); - showNotice(`密码已复制到剪贴板:${newPassword}`); - }} - /> + fluid + icon='lock' + iconPosition='left' + placeholder='新密码' + name='newPassword' + value={newPassword} + readOnly + onClick={(e) => { + e.target.select(); + navigator.clipboard.writeText(newPassword); + showNotice(`密码已复制到剪贴板:${newPassword}`); + }} + /> )}