Skip to content

Commit

Permalink
feat: allow baseUrl
Browse files Browse the repository at this point in the history
  • Loading branch information
haobibo committed Aug 6, 2024
1 parent f977469 commit 204f2ae
Show file tree
Hide file tree
Showing 17 changed files with 69 additions and 53 deletions.
4 changes: 3 additions & 1 deletion common/embed-file-system.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"github.com/gin-contrib/static"
"io/fs"
"net/http"
"strings"
)

// Credit: https://github.com/gin-contrib/static/issues/19
Expand All @@ -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
}

Expand Down
2 changes: 1 addition & 1 deletion router/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand Down
2 changes: 1 addition & 1 deletion router/dashboard.go
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
12 changes: 9 additions & 3 deletions router/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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))
})
}
Expand Down
2 changes: 1 addition & 1 deletion router/relay.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
16 changes: 9 additions & 7 deletions router/web.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions web/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
1 change: 1 addition & 0 deletions web/default/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"name": "react-template",
"version": "0.1.0",
"homepage": "",
"private": true,
"dependencies": {
"axios": "^0.27.2",
Expand Down
2 changes: 1 addition & 1 deletion web/default/public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<link rel="icon" href="logo.png" />
<link id="favicon" rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#ffffff" />
<meta
Expand Down
13 changes: 4 additions & 9 deletions web/default/src/components/Header.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useContext, useState } from 'react';
import { Link, useNavigate } from 'react-router-dom';
import { UserContext } from '../context/User';

import { BASE_URL } from "../config";
import { Button, Container, Dropdown, Icon, Menu, Segment } from 'semantic-ui-react';
import { API, getLogo, getSystemName, isAdmin, isMobile, showSuccess } from '../helpers';
import '../index.css';
Expand Down Expand Up @@ -119,19 +119,14 @@ const Header = () => {
size='large'
style={
showSidebar
? {
borderBottom: 'none',
marginBottom: '0',
borderTop: 'none',
height: '51px'
}
? { borderBottom: 'none', marginBottom: '0', borderTop: 'none', height: '51px' }
: { borderTop: 'none', height: '52px' }
}
>
<Container>
<Menu.Item as={Link} to='/'>
<img
src={logo}
src={ BASE_URL + logo}
alt='logo'
style={{ marginRight: '0.75em' }}
/>
Expand Down Expand Up @@ -188,7 +183,7 @@ const Header = () => {
<Menu borderless style={{ borderTop: 'none' }}>
<Container>
<Menu.Item as={Link} to='/' className={'hide-on-mobile'}>
<img src={logo} alt='logo' style={{ marginRight: '0.75em' }} />
<img src={ BASE_URL + logo} alt='logo' style={{ marginRight: '0.75em' }} />
<div style={{ fontSize: '20px' }}>
<b>{systemName}</b>
</div>
Expand Down
17 changes: 9 additions & 8 deletions web/default/src/components/LoginForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 = () => {
Expand Down Expand Up @@ -87,7 +88,7 @@ const LoginForm = () => {
<Grid textAlign='center' style={{ marginTop: '48px' }}>
<Grid.Column style={{ maxWidth: 450 }}>
<Header as='h2' color='' textAlign='center'>
<Image src={logo} /> 用户登录
<Image src={ BASE_URL + logo} /> 用户登录
</Header>
<Form size='large'>
<Segment>
Expand Down Expand Up @@ -151,13 +152,13 @@ const LoginForm = () => {
)}
{status.lark_client_id ? (
<div style={{
background: "radial-gradient(circle, #FFFFFF, #FFFFFF, #00D6B9, #2F73FF, #0a3A9C)",
width: "36px",
height: "36px",
borderRadius: "10em",
display: "flex",
cursor: "pointer"
}}
background: "radial-gradient(circle, #FFFFFF, #FFFFFF, #00D6B9, #2F73FF, #0a3A9C)",
width: "36px",
height: "36px",
borderRadius: "10em",
display: "flex",
cursor: "pointer"
}}
onClick={() => onLarkOAuthClicked(status.lark_client_id)}
>
<Image
Expand Down
35 changes: 18 additions & 17 deletions web/default/src/components/PasswordResetConfirm.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { useEffect, useState } from 'react';
import { Button, Form, Grid, Header, Image, Segment } from 'semantic-ui-react';
import { API, copy, showError, showInfo, showNotice, showSuccess } from '../helpers';
import { BASE_URL } from '../config';
import { useSearchParams } from 'react-router-dom';

const PasswordResetConfirm = () => {
Expand Down Expand Up @@ -37,7 +38,7 @@ const PasswordResetConfirm = () => {
setDisableButton(false);
setCountdown(30);
}
return () => clearInterval(countdownInterval);
return () => clearInterval(countdownInterval);
}, [disableButton, countdown]);

async function handleSubmit(e) {
Expand All @@ -59,12 +60,12 @@ const PasswordResetConfirm = () => {
}
setLoading(false);
}

return (
<Grid textAlign='center' style={{ marginTop: '48px' }}>
<Grid.Column style={{ maxWidth: 450 }}>
<Header as='h2' color='' textAlign='center'>
<Image src='/logo.png' /> 密码重置确认
<Image src={ BASE_URL + '/logo.png'} /> 密码重置确认
</Header>
<Form size='large'>
<Segment>
Expand All @@ -79,19 +80,19 @@ const PasswordResetConfirm = () => {
/>
{newPassword && (
<Form.Input
fluid
icon='lock'
iconPosition='left'
placeholder='新密码'
name='newPassword'
value={newPassword}
readOnly
onClick={(e) => {
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}`);
}}
/>
)}
<Button
color='green'
Expand All @@ -107,7 +108,7 @@ const PasswordResetConfirm = () => {
</Form>
</Grid.Column>
</Grid>
);
);
};

export default PasswordResetConfirm;
3 changes: 2 additions & 1 deletion web/default/src/components/PasswordResetForm.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { useEffect, useState } from 'react';
import { Button, Form, Grid, Header, Image, Segment } from 'semantic-ui-react';
import { API, showError, showInfo, showSuccess } from '../helpers';
import { BASE_URL } from '../config';
import Turnstile from 'react-turnstile';

const PasswordResetForm = () => {
Expand Down Expand Up @@ -70,7 +71,7 @@ const PasswordResetForm = () => {
<Grid textAlign='center' style={{ marginTop: '48px' }}>
<Grid.Column style={{ maxWidth: 450 }}>
<Header as='h2' color='' textAlign='center'>
<Image src='/logo.png' /> 密码重置
<Image src={ BASE_URL + '/logo.png'} /> 密码重置
</Header>
<Form size='large'>
<Segment>
Expand Down
3 changes: 2 additions & 1 deletion web/default/src/components/RegisterForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { useEffect, useState } from 'react';
import { Button, Form, Grid, Header, Image, Message, Segment } from 'semantic-ui-react';
import { Link, useNavigate } from 'react-router-dom';
import { API, getLogo, showError, showInfo, showSuccess } from '../helpers';
import { BASE_URL } from '../config';
import Turnstile from 'react-turnstile';

const RegisterForm = () => {
Expand Down Expand Up @@ -101,7 +102,7 @@ const RegisterForm = () => {
<Grid textAlign='center' style={{ marginTop: '48px' }}>
<Grid.Column style={{ maxWidth: 450 }}>
<Header as='h2' color='' textAlign='center'>
<Image src={logo} /> 新用户注册
<Image src={ BASE_URL + logo} /> 新用户注册
</Header>
<Form size='large'>
<Segment>
Expand Down
1 change: 1 addition & 0 deletions web/default/src/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const BASE_URL = process.env.REACT_APP_BASE_URL || '';
5 changes: 4 additions & 1 deletion web/default/src/helpers/api.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { showError } from './utils';
import { BASE_URL } from '../config';
import axios from 'axios';

export const API = axios.create({
baseURL: process.env.REACT_APP_SERVER ? process.env.REACT_APP_SERVER : '',
baseURL:
(process.env.REACT_APP_SERVER ? process.env.REACT_APP_SERVER : '') +
BASE_URL,
});

API.interceptors.response.use(
Expand Down
3 changes: 2 additions & 1 deletion web/default/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@ import { UserProvider } from './context/User';
import { ToastContainer } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
import { StatusProvider } from './context/Status';
import { BASE_URL } from './config';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<StatusProvider>
<UserProvider>
<BrowserRouter>
<BrowserRouter basename={BASE_URL}>
<Header />
<Container className={'main-content'}>
<App />
Expand Down

0 comments on commit 204f2ae

Please sign in to comment.