mirror of
https://github.com/whyour/qinglong.git
synced 2025-05-22 22:36:06 +08:00
支持非根目录部署
This commit is contained in:
parent
1377fe31aa
commit
490bdc15f6
|
@ -1,6 +1,7 @@
|
||||||
import { defineConfig } from '@umijs/max';
|
import { defineConfig } from '@umijs/max';
|
||||||
const CompressionPlugin = require('compression-webpack-plugin');
|
const CompressionPlugin = require('compression-webpack-plugin');
|
||||||
|
|
||||||
|
const baseUrl = process.env.QlBaseUrl || '/';
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
hash: true,
|
hash: true,
|
||||||
antd: {},
|
antd: {},
|
||||||
|
@ -12,15 +13,16 @@ export default defineConfig({
|
||||||
},
|
},
|
||||||
publicPath: process.env.NODE_ENV === 'production' ? './' : '/',
|
publicPath: process.env.NODE_ENV === 'production' ? './' : '/',
|
||||||
proxy: {
|
proxy: {
|
||||||
'/api/public': {
|
[`${baseUrl}api/public`]: {
|
||||||
target: 'http://127.0.0.1:5400/',
|
target: 'http://127.0.0.1:5400/',
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
pathRewrite: { '^/api/public': '/api/' },
|
pathRewrite: { [`^${baseUrl}api/public`]: '/api' },
|
||||||
},
|
},
|
||||||
'/api': {
|
[`${baseUrl}api`]: {
|
||||||
target: 'http://127.0.0.1:5600/',
|
target: 'http://127.0.0.1:5600/',
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
ws: true,
|
ws: true,
|
||||||
|
pathRewrite: { [`^${baseUrl}api`]: '/api' },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
chainWebpack: ((config: any) => {
|
chainWebpack: ((config: any) => {
|
||||||
|
@ -38,6 +40,7 @@ export default defineConfig({
|
||||||
'react-dom': 'window.ReactDOM',
|
'react-dom': 'window.ReactDOM',
|
||||||
},
|
},
|
||||||
headScripts: [
|
headScripts: [
|
||||||
|
'./api/env.js',
|
||||||
'https://gw.alipayobjects.com/os/lib/react/18.2.0/umd/react.production.min.js',
|
'https://gw.alipayobjects.com/os/lib/react/18.2.0/umd/react.production.min.js',
|
||||||
'https://gw.alipayobjects.com/os/lib/react-dom/18.2.0/umd/react-dom.production.min.js',
|
'https://gw.alipayobjects.com/os/lib/react-dom/18.2.0/umd/react-dom.production.min.js',
|
||||||
],
|
],
|
||||||
|
|
|
@ -92,6 +92,11 @@ export default {
|
||||||
'/api/system',
|
'/api/system',
|
||||||
'/api/user/init',
|
'/api/user/init',
|
||||||
'/api/user/notification/init',
|
'/api/user/notification/init',
|
||||||
|
'/open/user/login',
|
||||||
|
'/open/user/two-factor/login',
|
||||||
|
'/open/system',
|
||||||
|
'/open/user/init',
|
||||||
|
'/open/user/notification/init',
|
||||||
],
|
],
|
||||||
versionFile,
|
versionFile,
|
||||||
lastVersionFile,
|
lastVersionFile,
|
||||||
|
|
20
back/config/serverEnv.ts
Normal file
20
back/config/serverEnv.ts
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
import { Request, Response } from 'express';
|
||||||
|
import { pick } from 'lodash';
|
||||||
|
|
||||||
|
let pickedEnv: Record<string, string>;
|
||||||
|
|
||||||
|
function getPickedEnv() {
|
||||||
|
if (pickedEnv) return pickedEnv;
|
||||||
|
const picked = pick(process.env, ['QlBaseUrl']);
|
||||||
|
pickedEnv = picked as Record<string, string>;
|
||||||
|
return picked;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function serveEnv(_req: Request, res: Response) {
|
||||||
|
res.type('.js');
|
||||||
|
res.send(
|
||||||
|
Object.entries(getPickedEnv())
|
||||||
|
.map(([k, v]) => `window.__ENV__${k}=${JSON.stringify(v)};`)
|
||||||
|
.join('\n'),
|
||||||
|
);
|
||||||
|
}
|
|
@ -16,10 +16,12 @@ import { EnvModel } from '../data/env';
|
||||||
import { errors } from 'celebrate';
|
import { errors } from 'celebrate';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { createProxyMiddleware } from 'http-proxy-middleware';
|
import { createProxyMiddleware } from 'http-proxy-middleware';
|
||||||
|
import { serveEnv } from '../config/serverEnv';
|
||||||
|
|
||||||
export default ({ app }: { app: Application }) => {
|
export default ({ app }: { app: Application }) => {
|
||||||
app.enable('trust proxy');
|
app.enable('trust proxy');
|
||||||
app.use(cors());
|
app.use(cors());
|
||||||
|
app.get(`${config.api.prefix}/env.js`, serveEnv);
|
||||||
app.use(`${config.api.prefix}/static`, express.static(config.uploadPath));
|
app.use(`${config.api.prefix}/static`, express.static(config.uploadPath));
|
||||||
|
|
||||||
app.use(
|
app.use(
|
||||||
|
@ -31,27 +33,6 @@ export default ({ app }: { app: Application }) => {
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
app.use((req, res, next) => {
|
|
||||||
if (req.path.startsWith('/api') || req.path.startsWith('/open')) {
|
|
||||||
next();
|
|
||||||
} else {
|
|
||||||
return handler(req, res, {
|
|
||||||
public: path.join(config.rootPath, 'static/dist'),
|
|
||||||
rewrites: [{ source: '**', destination: '/index.html' }],
|
|
||||||
headers: [
|
|
||||||
{
|
|
||||||
source: 'index.html',
|
|
||||||
headers: [
|
|
||||||
{
|
|
||||||
key: 'Cache-Control',
|
|
||||||
value: 'no-cache',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
app.use(bodyParser.json({ limit: '50mb' }));
|
app.use(bodyParser.json({ limit: '50mb' }));
|
||||||
app.use(bodyParser.urlencoded({ limit: '50mb', extended: true }));
|
app.use(bodyParser.urlencoded({ limit: '50mb', extended: true }));
|
||||||
|
|
||||||
|
|
|
@ -14,10 +14,9 @@ map $http_upgrade $connection_upgrade {
|
||||||
server {
|
server {
|
||||||
listen 5700;
|
listen 5700;
|
||||||
IPV6_CONFIG
|
IPV6_CONFIG
|
||||||
root /ql/static/dist;
|
|
||||||
ssl_session_timeout 5m;
|
ssl_session_timeout 5m;
|
||||||
|
|
||||||
location QL_BASE_URL/api/public/ {
|
location QL_BASE_URLapi/public/ {
|
||||||
proxy_set_header Host $http_host;
|
proxy_set_header Host $http_host;
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
@ -25,7 +24,7 @@ server {
|
||||||
proxy_buffering off;
|
proxy_buffering off;
|
||||||
}
|
}
|
||||||
|
|
||||||
location QL_BASE_URL/api/ {
|
location QL_BASE_URLapi/ {
|
||||||
proxy_set_header Host $http_host;
|
proxy_set_header Host $http_host;
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
@ -36,7 +35,7 @@ server {
|
||||||
proxy_set_header Connection $connection_upgrade;
|
proxy_set_header Connection $connection_upgrade;
|
||||||
}
|
}
|
||||||
|
|
||||||
location QL_BASE_URL/open/ {
|
location QL_BASE_URLopen/ {
|
||||||
proxy_set_header Host $http_host;
|
proxy_set_header Host $http_host;
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
@ -53,9 +52,10 @@ server {
|
||||||
gzip_buffers 16 8k;
|
gzip_buffers 16 8k;
|
||||||
gzip_http_version 1.0;
|
gzip_http_version 1.0;
|
||||||
|
|
||||||
location QL_BASE_URL/ {
|
location QL_BASE_URL_LOCATION {
|
||||||
|
QL_ROOT_OR_ALIAS /ql/static/dist;
|
||||||
index index.html index.htm;
|
index index.html index.htm;
|
||||||
try_files $uri $uri/ QL_BASE_URL/index.html;
|
try_files $uri QL_BASE_URLindex.html;
|
||||||
}
|
}
|
||||||
|
|
||||||
location ~ .*\.(html)$ {
|
location ~ .*\.(html)$ {
|
||||||
|
|
|
@ -35,7 +35,6 @@ file_notify_js_sample=$dir_sample/notify.js
|
||||||
file_notify_py_sample=$dir_sample/notify.py
|
file_notify_py_sample=$dir_sample/notify.py
|
||||||
file_notify_py=$dir_scripts/notify.py
|
file_notify_py=$dir_scripts/notify.py
|
||||||
file_notify_js=$dir_scripts/sendNotify.js
|
file_notify_js=$dir_scripts/sendNotify.js
|
||||||
task_error_log_path=$dir_log/task_error.log
|
|
||||||
nginx_app_conf=$dir_root/docker/front.conf
|
nginx_app_conf=$dir_root/docker/front.conf
|
||||||
nginx_conf=$dir_root/docker/nginx.conf
|
nginx_conf=$dir_root/docker/nginx.conf
|
||||||
dep_notify_py=$dir_dep/notify.py
|
dep_notify_py=$dir_dep/notify.py
|
||||||
|
@ -68,7 +67,7 @@ import_config() {
|
||||||
[[ -f $file_config_user ]] && . $file_config_user
|
[[ -f $file_config_user ]] && . $file_config_user
|
||||||
[[ -f $file_env ]] && . $file_env
|
[[ -f $file_env ]] && . $file_env
|
||||||
|
|
||||||
ql_base_url=${QlBaseUrl:-""}
|
ql_base_url=${QlBaseUrl:-"/"}
|
||||||
command_timeout_time=${CommandTimeoutTime:-""}
|
command_timeout_time=${CommandTimeoutTime:-""}
|
||||||
proxy_url=${ProxyUrl:-""}
|
proxy_url=${ProxyUrl:-""}
|
||||||
file_extensions=${RepoFileExtensions:-"js py"}
|
file_extensions=${RepoFileExtensions:-"js py"}
|
||||||
|
@ -468,7 +467,15 @@ patch_version() {
|
||||||
init_nginx() {
|
init_nginx() {
|
||||||
cp -fv $nginx_conf /etc/nginx/nginx.conf
|
cp -fv $nginx_conf /etc/nginx/nginx.conf
|
||||||
cp -fv $nginx_app_conf /etc/nginx/conf.d/front.conf
|
cp -fv $nginx_app_conf /etc/nginx/conf.d/front.conf
|
||||||
sed -i "s,QL_BASE_URL,${qlBaseUrl},g" /etc/nginx/conf.d/front.conf
|
local location_url="/"
|
||||||
|
local root_or_alias="root"
|
||||||
|
if [[ $ql_base_url != "/" ]]; then
|
||||||
|
location_url="^~${ql_base_url%*/}"
|
||||||
|
root_or_alias="alias"
|
||||||
|
fi
|
||||||
|
sed -i "s,QL_BASE_URL_LOCATION,${location_url},g" /etc/nginx/conf.d/front.conf
|
||||||
|
sed -i "s,QL_BASE_URL,${ql_base_url},g" /etc/nginx/conf.d/front.conf
|
||||||
|
sed -i "s,QL_ROOT_OR_ALIAS,${root_or_alias},g" /etc/nginx/conf.d/front.conf
|
||||||
|
|
||||||
ipv6=$(ip a | grep inet6)
|
ipv6=$(ip a | grep inet6)
|
||||||
ipv6Str=""
|
ipv6Str=""
|
||||||
|
@ -485,11 +492,6 @@ handle_task_before() {
|
||||||
|
|
||||||
[[ $is_macos -eq 0 ]] && check_server
|
[[ $is_macos -eq 0 ]] && check_server
|
||||||
|
|
||||||
if [[ -s $task_error_log_path ]]; then
|
|
||||||
cat $task_error_log_path
|
|
||||||
echo -e "加载 config.sh 出错,请手动检查"
|
|
||||||
fi
|
|
||||||
|
|
||||||
. $file_task_before "$@"
|
. $file_task_before "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -513,4 +515,4 @@ detect_termux
|
||||||
detect_macos
|
detect_macos
|
||||||
define_cmd
|
define_cmd
|
||||||
|
|
||||||
import_config $1 2>$task_error_log_path
|
import_config $1
|
||||||
|
|
|
@ -457,12 +457,6 @@ main() {
|
||||||
eval echo -e "\#\# 开始执行... $begin_time\\\n" $cmd
|
eval echo -e "\#\# 开始执行... $begin_time\\\n" $cmd
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -s $task_error_log_path ]]; then
|
|
||||||
eval cat $task_error_log_path $cmd
|
|
||||||
eval echo -e "加载 config.sh 出错,请手动检查" $cmd
|
|
||||||
eval echo $cmd
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "$show_log" == "true" ]] && [[ $ID ]]; then
|
if [[ "$show_log" == "true" ]] && [[ $ID ]]; then
|
||||||
eval echo -e "请移除 -l 参数" $cmd
|
eval echo -e "请移除 -l 参数" $cmd
|
||||||
exit 1
|
exit 1
|
||||||
|
|
16
src/app.ts
Normal file
16
src/app.ts
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
const baseUrl = window.__ENV__QlBaseUrl || '/';
|
||||||
|
|
||||||
|
export function modifyClientRenderOpts(memo: any) {
|
||||||
|
return {
|
||||||
|
...memo,
|
||||||
|
publicPath: baseUrl,
|
||||||
|
basename: baseUrl,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function modifyContextOpts(memo: any) {
|
||||||
|
return {
|
||||||
|
...memo,
|
||||||
|
basename: baseUrl,
|
||||||
|
};
|
||||||
|
}
|
|
@ -332,8 +332,14 @@ select:-webkit-autofill:focus {
|
||||||
}
|
}
|
||||||
|
|
||||||
.ant-pro-sider-logo {
|
.ant-pro-sider-logo {
|
||||||
h1 {
|
.title {
|
||||||
margin-left: 5px !important;
|
height: 32px;
|
||||||
|
margin: 0 5px;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 32px;
|
||||||
|
vertical-align: middle;
|
||||||
|
animation: pro-layout-title-hide 0.3s;
|
||||||
}
|
}
|
||||||
|
|
||||||
img {
|
img {
|
||||||
|
|
|
@ -280,11 +280,10 @@ export default function () {
|
||||||
selectedKeys={[location.pathname]}
|
selectedKeys={[location.pathname]}
|
||||||
loading={loading}
|
loading={loading}
|
||||||
ErrorBoundary={Sentry.ErrorBoundary}
|
ErrorBoundary={Sentry.ErrorBoundary}
|
||||||
logo={<Image preview={false} src="https://qn.whyour.cn/logo.png" />}
|
logo={
|
||||||
// @ts-ignore
|
|
||||||
title={
|
|
||||||
<>
|
<>
|
||||||
<span style={{ fontSize: 16, marginRight: 5 }}>青龙</span>
|
<Image preview={false} src="https://qn.whyour.cn/logo.png" />
|
||||||
|
<span className="title">青龙</span>
|
||||||
<a
|
<a
|
||||||
href={systemInfo?.changeLogLink}
|
href={systemInfo?.changeLogLink}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
|
@ -313,6 +312,7 @@ export default function () {
|
||||||
</a>
|
</a>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
|
title={false}
|
||||||
menuItemRender={(menuItemProps: any, defaultDom: any) => {
|
menuItemRender={(menuItemProps: any, defaultDom: any) => {
|
||||||
if (
|
if (
|
||||||
menuItemProps.isUrl ||
|
menuItemProps.isUrl ||
|
||||||
|
|
|
@ -17,9 +17,9 @@ const Error = () => {
|
||||||
needLoading && setLoading(true);
|
needLoading && setLoading(true);
|
||||||
request
|
request
|
||||||
.get(`${config.apiPrefix}public/health`)
|
.get(`${config.apiPrefix}public/health`)
|
||||||
.then(({ error, status }) => {
|
.then(({ error, data }) => {
|
||||||
if (status === 1) {
|
if (data?.status === 1) {
|
||||||
return reloadUser();
|
return;
|
||||||
}
|
}
|
||||||
if (retryTimes.current > 3) {
|
if (retryTimes.current > 3) {
|
||||||
setData(error?.details);
|
setData(error?.details);
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
|
const baseUrl = window.__ENV__QlBaseUrl || '/';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
siteName: '青龙',
|
siteName: '青龙',
|
||||||
apiPrefix: '/api/',
|
apiPrefix: `${baseUrl}api/`,
|
||||||
authKey: 'token',
|
authKey: 'token',
|
||||||
|
|
||||||
/* Layout configuration, specify which layout to use for route. */
|
/* Layout configuration, specify which layout to use for route. */
|
||||||
|
|
4
typings.d.ts
vendored
4
typings.d.ts
vendored
|
@ -10,3 +10,7 @@ declare module '*.svg' {
|
||||||
}
|
}
|
||||||
|
|
||||||
declare module 'pstree.remy';
|
declare module 'pstree.remy';
|
||||||
|
|
||||||
|
interface Window {
|
||||||
|
__ENV__QlBaseUrl: string;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user