chore: sync local changes (2026-03-12)
This commit is contained in:
@@ -1,43 +0,0 @@
|
|||||||
# 贡献指南
|
|
||||||
|
|
||||||
感谢你对萌芽短链接项目的关注!我们欢迎任何形式的贡献。
|
|
||||||
|
|
||||||
## 🤝 如何参与
|
|
||||||
|
|
||||||
1. **Fork 本仓库**:点击右上角的 Fork 按钮,将仓库复刻到你的 GitHub 账号下。
|
|
||||||
2. **Clone 仓库**:将 Fork 后的仓库克隆到本地。
|
|
||||||
```bash
|
|
||||||
git clone https://github.com/your-username/mengyalinkfly.git
|
|
||||||
```
|
|
||||||
3. **创建分支**:为你的修改创建一个新的分支。
|
|
||||||
```bash
|
|
||||||
git checkout -b feature/AmazingFeature
|
|
||||||
```
|
|
||||||
4. **提交修改**:
|
|
||||||
- 请确保代码风格统一。
|
|
||||||
- 提交信息请清晰描述修改内容。
|
|
||||||
```bash
|
|
||||||
git commit -m 'Add some AmazingFeature'
|
|
||||||
```
|
|
||||||
5. **推送到远程**:
|
|
||||||
```bash
|
|
||||||
git push origin feature/AmazingFeature
|
|
||||||
```
|
|
||||||
6. **提交 Pull Request**:在 GitHub 上发起 Pull Request,我们将尽快审核。
|
|
||||||
|
|
||||||
## 🐛 提交 Issue
|
|
||||||
|
|
||||||
如果你发现了 Bug 或有功能建议,欢迎提交 Issue。请包含以下信息:
|
|
||||||
|
|
||||||
- 问题描述
|
|
||||||
- 复现步骤
|
|
||||||
- 预期行为
|
|
||||||
- 截图(如果有)
|
|
||||||
- 环境信息(OS, Browser, etc.)
|
|
||||||
|
|
||||||
## 📄 代码规范
|
|
||||||
|
|
||||||
- **前端**:遵循 React 最佳实践,使用 ESLint 进行检查。
|
|
||||||
- **后端**:遵循 PEP 8 规范。
|
|
||||||
|
|
||||||
再次感谢你的贡献!
|
|
||||||
50
Dockerfile
50
Dockerfile
@@ -1,50 +0,0 @@
|
|||||||
# 使用多阶段构建
|
|
||||||
# 阶段1: 构建前端
|
|
||||||
FROM node:18-alpine AS frontend-builder
|
|
||||||
|
|
||||||
WORKDIR /app/frontend
|
|
||||||
|
|
||||||
# 复制前端文件
|
|
||||||
COPY mengyalinkfly-frontend/package*.json ./
|
|
||||||
RUN npm install
|
|
||||||
|
|
||||||
COPY mengyalinkfly-frontend/ ./
|
|
||||||
RUN npm run build
|
|
||||||
|
|
||||||
# 阶段2: 最终镜像
|
|
||||||
FROM python:3.11-slim
|
|
||||||
|
|
||||||
WORKDIR /app
|
|
||||||
|
|
||||||
# 安装 nginx 和必要的工具
|
|
||||||
RUN apt-get update && \
|
|
||||||
apt-get install -y nginx && \
|
|
||||||
apt-get clean && \
|
|
||||||
rm -rf /var/lib/apt/lists/*
|
|
||||||
|
|
||||||
# 复制后端文件
|
|
||||||
COPY mengyalinkfly-backend/ ./backend/
|
|
||||||
|
|
||||||
# 安装 Python 依赖
|
|
||||||
RUN pip install --no-cache-dir -r ./backend/requirements.txt && \
|
|
||||||
pip install --no-cache-dir gunicorn
|
|
||||||
|
|
||||||
# 从前端构建阶段复制构建产物
|
|
||||||
COPY --from=frontend-builder /app/frontend/dist ./frontend/dist
|
|
||||||
|
|
||||||
# 创建持久化数据目录
|
|
||||||
RUN mkdir -p /shumengya/docker/storage/mengyalinkfly
|
|
||||||
|
|
||||||
# 复制 nginx 配置和启动脚本
|
|
||||||
COPY docker/nginx.conf /etc/nginx/sites-available/default
|
|
||||||
COPY docker/start.sh /app/start.sh
|
|
||||||
RUN chmod +x /app/start.sh
|
|
||||||
|
|
||||||
# 暴露端口
|
|
||||||
EXPOSE 7878
|
|
||||||
|
|
||||||
# 设置工作目录
|
|
||||||
WORKDIR /app/backend
|
|
||||||
|
|
||||||
# 启动服务
|
|
||||||
CMD ["/app/start.sh"]
|
|
||||||
7
build-frontend.bat
Normal file
7
build-frontend.bat
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
@echo off
|
||||||
|
chcp 65001 >nul
|
||||||
|
echo 构建前端项目...
|
||||||
|
cd mengyalinkfly-frontend
|
||||||
|
echo 正在安装依赖...
|
||||||
|
call npm install
|
||||||
|
npm run build
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
services:
|
|
||||||
mengyalinkfly:
|
|
||||||
build: .
|
|
||||||
container_name: mengyalinkfly
|
|
||||||
ports:
|
|
||||||
- "7878:7878"
|
|
||||||
volumes:
|
|
||||||
- /shumengya/docker/storage/mengyalinkfly:/shumengya/docker/storage/mengyalinkfly
|
|
||||||
restart: unless-stopped
|
|
||||||
environment:
|
|
||||||
- TZ=Asia/Shanghai
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
server {
|
|
||||||
listen 7878;
|
|
||||||
server_name _;
|
|
||||||
root /app/frontend/dist;
|
|
||||||
index index.html;
|
|
||||||
|
|
||||||
# 静态内容优先走前端
|
|
||||||
location / {
|
|
||||||
try_files $uri $uri/ /index.html @backend;
|
|
||||||
add_header Cache-Control "no-cache, must-revalidate";
|
|
||||||
}
|
|
||||||
|
|
||||||
# 后端 API 代理
|
|
||||||
location /api {
|
|
||||||
proxy_pass http://127.0.0.1:5000;
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
}
|
|
||||||
|
|
||||||
# 兜底转发到后端(短链跳转)
|
|
||||||
location @backend {
|
|
||||||
proxy_pass http://127.0.0.1:5000;
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
}
|
|
||||||
|
|
||||||
# 静态资源缓存策略
|
|
||||||
location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg)$ {
|
|
||||||
expires 1y;
|
|
||||||
add_header Cache-Control "public, immutable";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# 如果持久化目录中有数据文件,使用它;否则创建新的
|
|
||||||
if [ -f /shumengya/docker/storage/mengyalinkfly/link_data.json ]; then
|
|
||||||
echo "使用持久化的数据文件..."
|
|
||||||
ln -sf /shumengya/docker/storage/mengyalinkfly/link_data.json /app/backend/link_data.json
|
|
||||||
else
|
|
||||||
echo "创建新的数据文件..."
|
|
||||||
echo '{}' > /shumengya/docker/storage/mengyalinkfly/link_data.json
|
|
||||||
ln -sf /shumengya/docker/storage/mengyalinkfly/link_data.json /app/backend/link_data.json
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 启动 nginx
|
|
||||||
echo "启动 Nginx..."
|
|
||||||
nginx
|
|
||||||
|
|
||||||
# 启动 Flask 后端(使用 gunicorn)
|
|
||||||
echo "启动 Flask 后端..."
|
|
||||||
cd /app/backend
|
|
||||||
exec gunicorn -w 4 -b 0.0.0.0:5000 app:app
|
|
||||||
20
mengyalinkfly-backend/Dockerfile
Normal file
20
mengyalinkfly-backend/Dockerfile
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
# 纯后端Docker镜像(前端单独部署)
|
||||||
|
FROM python:3.11-slim
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# 复制后端文件
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
# 安装 Python 依赖
|
||||||
|
RUN pip install --no-cache-dir -r requirements.txt && \
|
||||||
|
pip install --no-cache-dir gunicorn
|
||||||
|
|
||||||
|
# 创建持久化数据目录
|
||||||
|
RUN mkdir -p /app/data
|
||||||
|
|
||||||
|
# 暴露端口
|
||||||
|
EXPOSE 7878
|
||||||
|
|
||||||
|
# 启动服务(使用gunicorn)
|
||||||
|
CMD ["gunicorn", "-w", "4", "-b", "0.0.0.0:7878", "app:app"]
|
||||||
@@ -7,9 +7,20 @@ import string
|
|||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
CORS(app)
|
# 配置CORS允许前端服务器访问
|
||||||
|
CORS(app, origins=[
|
||||||
|
"http://192.168.1.100:8989", # 前端服务器
|
||||||
|
"http://localhost:8989", # 本地测试
|
||||||
|
"http://127.0.0.1:8989", # 本地测试
|
||||||
|
"http://short.shumengya.top", # 前端域名(如果有)
|
||||||
|
"https://short.shumengya.top" # 前端域名HTTPS(如果有)
|
||||||
|
])
|
||||||
|
|
||||||
DATA_FILE = 'link_data.json'
|
# 数据文件路径(支持持久化挂载)
|
||||||
|
DATA_DIR = os.getenv('DATA_DIR', '/app/data')
|
||||||
|
if not os.path.exists(DATA_DIR):
|
||||||
|
os.makedirs(DATA_DIR)
|
||||||
|
DATA_FILE = os.path.join(DATA_DIR, 'link_data.json')
|
||||||
|
|
||||||
def load_links():
|
def load_links():
|
||||||
"""加载链接数据"""
|
"""加载链接数据"""
|
||||||
|
|||||||
19
mengyalinkfly-backend/docker-compose.yml
Normal file
19
mengyalinkfly-backend/docker-compose.yml
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
services:
|
||||||
|
mengyalinkfly-backend:
|
||||||
|
build: .
|
||||||
|
container_name: mengyalinkfly-backend
|
||||||
|
ports:
|
||||||
|
- "7878:7878"
|
||||||
|
volumes:
|
||||||
|
# 数据持久化目录
|
||||||
|
- /shumengya/docker/mengyalinkfly:/app/data
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
- TZ=Asia/Shanghai
|
||||||
|
- PYTHONUNBUFFERED=1
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "curl -f http://localhost:7878/ || exit 1"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
start_period: 40s
|
||||||
39
mengyalinkfly-backend/docker-run.sh
Normal file
39
mengyalinkfly-backend/docker-run.sh
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# 后端Docker部署脚本
|
||||||
|
|
||||||
|
echo "========== 萌芽短链后端部署 =========="
|
||||||
|
|
||||||
|
# 停止并删除旧容器
|
||||||
|
echo "停止旧容器..."
|
||||||
|
docker stop mengyalinkfly-backend 2>/dev/null
|
||||||
|
docker rm mengyalinkfly-backend 2>/dev/null
|
||||||
|
|
||||||
|
# 构建新镜像
|
||||||
|
echo "构建Docker镜像..."
|
||||||
|
docker build -t mengyalinkfly-backend:latest .
|
||||||
|
|
||||||
|
# 创建数据目录
|
||||||
|
echo "创建数据目录..."
|
||||||
|
mkdir -p /shumengya/docker/storage/mengyalinkfly
|
||||||
|
|
||||||
|
# 运行容器
|
||||||
|
echo "启动Docker容器..."
|
||||||
|
docker run -d \
|
||||||
|
--name mengyalinkfly-backend \
|
||||||
|
-p 7878:7878 \
|
||||||
|
-v /shumengya/docker/storage/mengyalinkfly:/app/data \
|
||||||
|
-e TZ=Asia/Shanghai \
|
||||||
|
--restart unless-stopped \
|
||||||
|
mengyalinkfly-backend:latest
|
||||||
|
|
||||||
|
# 检查状态
|
||||||
|
echo ""
|
||||||
|
echo "========== 部署完成 =========="
|
||||||
|
echo "容器状态:"
|
||||||
|
docker ps | grep mengyalinkfly-backend
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "查看日志:"
|
||||||
|
echo "docker logs -f mengyalinkfly-backend"
|
||||||
|
echo ""
|
||||||
|
echo "后端API地址:http://localhost:7878"
|
||||||
53
mengyalinkfly-frontend/build-and-deploy.sh
Normal file
53
mengyalinkfly-frontend/build-and-deploy.sh
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# 前端构建和部署脚本
|
||||||
|
|
||||||
|
echo "========== 萌芽短链前端部署 =========="
|
||||||
|
|
||||||
|
# 安装依赖
|
||||||
|
echo "安装依赖..."
|
||||||
|
npm install
|
||||||
|
|
||||||
|
# 构建
|
||||||
|
echo "构建前端..."
|
||||||
|
npm run build
|
||||||
|
|
||||||
|
# 创建部署目录
|
||||||
|
echo "创建部署目录..."
|
||||||
|
mkdir -p /shumengya/www/mengyalinkfly-frontend
|
||||||
|
|
||||||
|
# 备份旧文件
|
||||||
|
if [ -d "/shumengya/www/mengyalinkfly-frontend/index.html" ]; then
|
||||||
|
echo "备份旧版本..."
|
||||||
|
backup_dir="/shumengya/www/mengyalinkfly-frontend-backup-$(date +%Y%m%d-%H%M%S)"
|
||||||
|
mkdir -p "$backup_dir"
|
||||||
|
cp -r /shumengya/www/mengyalinkfly-frontend/* "$backup_dir/"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 部署新文件
|
||||||
|
echo "部署新文件..."
|
||||||
|
cp -r dist/* /shumengya/www/mengyalinkfly-frontend/
|
||||||
|
|
||||||
|
# 复制nginx配置
|
||||||
|
echo "更新nginx配置..."
|
||||||
|
cp ../nginx.conf /etc/nginx/sites-available/mengyalinkfly
|
||||||
|
|
||||||
|
# 创建软链接(如果不存在)
|
||||||
|
if [ ! -L "/etc/nginx/sites-enabled/mengyalinkfly" ]; then
|
||||||
|
ln -s /etc/nginx/sites-available/mengyalinkfly /etc/nginx/sites-enabled/
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 测试nginx配置
|
||||||
|
echo "测试nginx配置..."
|
||||||
|
nginx -t
|
||||||
|
|
||||||
|
# 重启nginx
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
echo "重启nginx..."
|
||||||
|
systemctl restart nginx
|
||||||
|
echo ""
|
||||||
|
echo "========== 部署完成 =========="
|
||||||
|
echo "前端地址:http://localhost:8989"
|
||||||
|
else
|
||||||
|
echo "Nginx配置错误,请检查!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
@@ -4,8 +4,13 @@
|
|||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<link rel="icon" type="image/png" href="/logo.png" />
|
<link rel="icon" type="image/png" href="/logo.png" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>萌芽短链</title>
|
<meta name="theme-color" content="#1a1a2e" />
|
||||||
<meta name="description" content="萌芽短链接,简单、快速的短链接生成工具" />
|
<meta name="description" content="萌芽短链接,简单、快速的短链接生成工具" />
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
||||||
|
<meta name="apple-mobile-web-app-title" content="萌芽短链" />
|
||||||
|
<link rel="apple-touch-icon" href="/logo.png" />
|
||||||
|
<title>萌芽短链</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
|
|||||||
41
mengyalinkfly-frontend/nginx.conf
Normal file
41
mengyalinkfly-frontend/nginx.conf
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
server {
|
||||||
|
listen 8989;
|
||||||
|
server_name mengyalinkfly-frontend; # 前端服务器IP
|
||||||
|
|
||||||
|
root /shumengya/www/mengyalinkfly-frontend;
|
||||||
|
index index.html index.htm;
|
||||||
|
|
||||||
|
# 短链跳转:4位字符的路径直接转发到后端服务器(支持wget等命令行工具)
|
||||||
|
location ~ "^/[a-zA-Z0-9]{4}$" {
|
||||||
|
proxy_pass http://192.168.1.233:7878;
|
||||||
|
proxy_set_header Host short.api.shumengya.top;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
}
|
||||||
|
|
||||||
|
# 后端 API 代理到后端服务器
|
||||||
|
location /api {
|
||||||
|
proxy_pass http://192.168.1.233:7878;
|
||||||
|
proxy_set_header Host short.api.shumengya.top;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
}
|
||||||
|
|
||||||
|
# 前端路由
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ /index.html;
|
||||||
|
}
|
||||||
|
|
||||||
|
# 禁止访问隐藏文件
|
||||||
|
location ~ /\. {
|
||||||
|
deny all;
|
||||||
|
}
|
||||||
|
|
||||||
|
# 设置静态文件缓存
|
||||||
|
location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg)$ {
|
||||||
|
expires 30d;
|
||||||
|
add_header Cache-Control "public, immutable";
|
||||||
|
}
|
||||||
|
}
|
||||||
4244
mengyalinkfly-frontend/package-lock.json
generated
4244
mengyalinkfly-frontend/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -24,6 +24,7 @@
|
|||||||
"eslint-plugin-react-hooks": "^7.0.1",
|
"eslint-plugin-react-hooks": "^7.0.1",
|
||||||
"eslint-plugin-react-refresh": "^0.4.24",
|
"eslint-plugin-react-refresh": "^0.4.24",
|
||||||
"globals": "^16.5.0",
|
"globals": "^16.5.0",
|
||||||
"vite": "^7.2.2"
|
"vite": "^7.2.2",
|
||||||
|
"vite-plugin-pwa": "^1.2.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,22 @@
|
|||||||
import { StrictMode } from 'react'
|
import { StrictMode } from 'react'
|
||||||
import { createRoot } from 'react-dom/client'
|
import { createRoot } from 'react-dom/client'
|
||||||
import { BrowserRouter } from 'react-router-dom'
|
import { BrowserRouter } from 'react-router-dom'
|
||||||
|
import { registerSW } from 'virtual:pwa-register'
|
||||||
import './index.css'
|
import './index.css'
|
||||||
import App from './App.jsx'
|
import App from './App.jsx'
|
||||||
|
|
||||||
|
// 注册 PWA Service Worker(支持更新提示)
|
||||||
|
if (import.meta.env.PROD) {
|
||||||
|
registerSW({
|
||||||
|
onNeedRefresh() {
|
||||||
|
// 可选:有新版本时提示用户刷新,当前为 autoUpdate 会自动更新
|
||||||
|
},
|
||||||
|
onOfflineReady() {
|
||||||
|
console.log('PWA: 内容已缓存,可离线使用')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
createRoot(document.getElementById('root')).render(
|
createRoot(document.getElementById('root')).render(
|
||||||
<StrictMode>
|
<StrictMode>
|
||||||
<BrowserRouter>
|
<BrowserRouter>
|
||||||
|
|||||||
@@ -1,9 +1,58 @@
|
|||||||
import { defineConfig } from 'vite'
|
import { defineConfig } from 'vite'
|
||||||
import react from '@vitejs/plugin-react'
|
import react from '@vitejs/plugin-react'
|
||||||
|
import { VitePWA } from 'vite-plugin-pwa'
|
||||||
|
|
||||||
// https://vite.dev/config/
|
// https://vite.dev/config/
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [react()],
|
plugins: [
|
||||||
|
react(),
|
||||||
|
VitePWA({
|
||||||
|
registerType: 'autoUpdate', // 自动更新 Service Worker,也可选 'prompt' 提示用户
|
||||||
|
includeAssets: ['logo.png', 'favicon.ico'],
|
||||||
|
manifest: {
|
||||||
|
name: '萌芽短链',
|
||||||
|
short_name: '萌芽短链',
|
||||||
|
description: '简单、快速的短链接生成工具',
|
||||||
|
theme_color: '#1a1a2e',
|
||||||
|
background_color: '#16213e',
|
||||||
|
display: 'standalone',
|
||||||
|
orientation: 'portrait-primary',
|
||||||
|
scope: '/',
|
||||||
|
start_url: '/',
|
||||||
|
lang: 'zh-CN',
|
||||||
|
icons: [
|
||||||
|
{
|
||||||
|
src: '/logo.png',
|
||||||
|
sizes: '192x192',
|
||||||
|
type: 'image/png',
|
||||||
|
purpose: 'any'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
src: '/logo.png',
|
||||||
|
sizes: '512x512',
|
||||||
|
type: 'image/png',
|
||||||
|
purpose: 'any maskable'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
workbox: {
|
||||||
|
globPatterns: ['**/*.{js,css,html,ico,png,svg,woff2}'],
|
||||||
|
globIgnores: ['**/background/*.png'], // 背景图过大,不预缓存,在线时再加载
|
||||||
|
runtimeCaching: [
|
||||||
|
{
|
||||||
|
urlPattern: /^https?:\/\/.*\/api\/.*/i,
|
||||||
|
handler: 'NetworkFirst',
|
||||||
|
options: {
|
||||||
|
cacheName: 'api-cache',
|
||||||
|
expiration: { maxEntries: 32, maxAgeSeconds: 60 * 5 },
|
||||||
|
cacheableResponse: { statuses: [0, 200] },
|
||||||
|
networkTimeoutSeconds: 10
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
],
|
||||||
server: {
|
server: {
|
||||||
host: '0.0.0.0',
|
host: '0.0.0.0',
|
||||||
port: 5173,
|
port: 5173,
|
||||||
|
|||||||
20
启动.bat
20
启动.bat
@@ -1,20 +0,0 @@
|
|||||||
@echo off
|
|
||||||
chcp 65001 >nul
|
|
||||||
title 萌芽短链接 - 一键启动
|
|
||||||
|
|
||||||
echo.
|
|
||||||
echo ========================================
|
|
||||||
echo 🌱 萌芽短链接 - 一键启动
|
|
||||||
echo ========================================
|
|
||||||
echo.
|
|
||||||
echo 正在启动前后端服务...
|
|
||||||
echo.
|
|
||||||
|
|
||||||
start "萌芽短链接-后端" cmd /k "cd /d "%~dp0" && start-backend.bat"
|
|
||||||
timeout /t 2 /nobreak >nul
|
|
||||||
|
|
||||||
start "萌芽短链接-前端" cmd /k "cd /d "%~dp0" && start-frontend.bat"
|
|
||||||
|
|
||||||
|
|
||||||
echo 按任意键退出此窗口...
|
|
||||||
pause >nul
|
|
||||||
139
部署说明.md
Normal file
139
部署说明.md
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
# 萌芽短链 - 前后端分离部署说明
|
||||||
|
|
||||||
|
## 架构说明
|
||||||
|
|
||||||
|
- **前端**:构建为静态HTML文件,部署在Nginx服务器(8989端口)
|
||||||
|
- **后端**:部署在Docker容器中(7878端口)
|
||||||
|
|
||||||
|
## 部署步骤
|
||||||
|
|
||||||
|
### 一、后端部署(Docker容器)
|
||||||
|
|
||||||
|
1. **构建Docker镜像**
|
||||||
|
```bash
|
||||||
|
cd mengyalinkfly-backend
|
||||||
|
docker build -t mengyalinkfly-backend:latest .
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **运行Docker容器**
|
||||||
|
```bash
|
||||||
|
docker run -d \
|
||||||
|
--name mengyalinkfly-backend \
|
||||||
|
-p 7878:7878 \
|
||||||
|
-v /shumengya/docker/storage/mengyalinkfly:/app/data \
|
||||||
|
--restart unless-stopped \
|
||||||
|
mengyalinkfly-backend:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **查看容器日志**
|
||||||
|
```bash
|
||||||
|
docker logs -f mengyalinkfly-backend
|
||||||
|
```
|
||||||
|
|
||||||
|
### 二、前端部署(静态文件)
|
||||||
|
|
||||||
|
1. **构建前端**
|
||||||
|
```bash
|
||||||
|
cd mengyalinkfly-frontend
|
||||||
|
npm install
|
||||||
|
npm run build
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **部署到Nginx**
|
||||||
|
```bash
|
||||||
|
# 复制构建产物到服务器
|
||||||
|
cp -r dist/* /shumengya/www/mengyalinkfly-frontend/
|
||||||
|
|
||||||
|
# 复制nginx配置(根目录下的nginx.conf)
|
||||||
|
cp nginx.conf /etc/nginx/sites-available/mengyalinkfly
|
||||||
|
ln -s /etc/nginx/sites-available/mengyalinkfly /etc/nginx/sites-enabled/
|
||||||
|
|
||||||
|
# 测试nginx配置
|
||||||
|
nginx -t
|
||||||
|
|
||||||
|
# 重启nginx
|
||||||
|
systemctl restart nginx
|
||||||
|
```
|
||||||
|
|
||||||
|
## 配置说明
|
||||||
|
|
||||||
|
### 1. 修改前端服务器地址
|
||||||
|
|
||||||
|
编辑 `nginx.conf`,将 `localhost` 替换为实际的后端服务器IP(如果前后端不在同一台机器):
|
||||||
|
|
||||||
|
```nginx
|
||||||
|
# 如果后端在其他服务器,修改为实际IP
|
||||||
|
location /api {
|
||||||
|
proxy_pass http://后端服务器IP:7878;
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
location ~ ^/[a-zA-Z0-9]{4}$ {
|
||||||
|
proxy_pass http://后端服务器IP:7878;
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 修改CORS配置
|
||||||
|
|
||||||
|
编辑 `mengyalinkfly-backend/app.py`,添加你的前端域名:
|
||||||
|
|
||||||
|
```python
|
||||||
|
CORS(app, origins=[
|
||||||
|
"http://localhost:8989",
|
||||||
|
"http://127.0.0.1:8989",
|
||||||
|
"http://your-frontend-domain.com" # 添加你的实际域名
|
||||||
|
])
|
||||||
|
```
|
||||||
|
|
||||||
|
## 访问方式
|
||||||
|
|
||||||
|
- **前端页面**:http://your-server:8989
|
||||||
|
- **后端API**:http://your-server:7878/api/*
|
||||||
|
- **短链跳转**:http://your-server:8989/XXXX (4位短链代码)
|
||||||
|
|
||||||
|
## 功能特点
|
||||||
|
|
||||||
|
✅ **支持浏览器访问** - 通过前端页面创建和管理短链接
|
||||||
|
✅ **支持命令行工具** - wget、curl可直接下载文件(自动HTTP 302重定向)
|
||||||
|
✅ **前后端分离** - 易于扩展和维护
|
||||||
|
✅ **Docker容器化** - 后端一键部署
|
||||||
|
|
||||||
|
## 测试命令
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 测试后端API
|
||||||
|
curl http://localhost:7878/api/links
|
||||||
|
|
||||||
|
# 测试短链跳转(浏览器)
|
||||||
|
curl -L http://localhost:8989/4GLS
|
||||||
|
|
||||||
|
# 测试wget下载(命令行)
|
||||||
|
wget http://localhost:8989/4GLS
|
||||||
|
```
|
||||||
|
|
||||||
|
## 目录结构
|
||||||
|
|
||||||
|
```
|
||||||
|
/shumengya/
|
||||||
|
├── www/
|
||||||
|
│ └── mengyalinkfly-frontend/ # 前端静态文件目录
|
||||||
|
│ ├── index.html
|
||||||
|
│ ├── assets/
|
||||||
|
│ └── ...
|
||||||
|
└── docker/
|
||||||
|
└── storage/
|
||||||
|
└── mengyalinkfly/ # 后端数据持久化目录
|
||||||
|
└── link_data.json
|
||||||
|
```
|
||||||
|
|
||||||
|
## 常见问题
|
||||||
|
|
||||||
|
### 1. wget下载HTML而不是文件?
|
||||||
|
确保nginx配置中有短链匹配规则,并且优先级在前端路由之前。
|
||||||
|
|
||||||
|
### 2. API跨域错误?
|
||||||
|
检查后端的CORS配置,确保包含了前端域名。
|
||||||
|
|
||||||
|
### 3. 容器无法启动?
|
||||||
|
检查端口7878是否被占用:`netstat -tulpn | grep 7878`
|
||||||
Reference in New Issue
Block a user