feat: 端口改为 1219,install.sh 支持 systemd 后台部署,增加目录非 git 仓库时自动重建

This commit is contained in:
auto-bot
2026-06-13 17:11:28 +00:00
parent a866d59053
commit d2255b5951
9 changed files with 334 additions and 193 deletions

View File

@@ -11,7 +11,7 @@ QZMusic 网页版,基于 Vue 3 + TypeScript + Vite 构建的音乐播放器,
- 📊 音频可视化(基于 Web Audio API
- 🔍 搜索功能
- 🔌 **插件系统** - 支持通过插件获取音乐资源
- 🌐 默认端口10096
- 🌐 默认端口1219
## 快速开始
@@ -62,7 +62,7 @@ bash uninstall.sh
卸载将删除:
- 安装目录(`/opt/QZMusic-Web`
- 端口 10096 上的所有进程
- 端口 1219 上的所有进程
- Systemd 服务(如有)
- npm 全局包(如有)
- 相关缓存文件
@@ -81,7 +81,7 @@ npm install
npm run dev
```
服务器将在 http://localhost:10096 启动
服务器将在 http://localhost:1219 启动
### 构建生产版本
@@ -101,9 +101,9 @@ npm run preview
| 命令 | 说明 |
|------|------|
| `npm run dev` | 启动开发服务器(端口 10096 |
| `npm run dev` | 启动开发服务器(端口 1219 |
| `npm run build` | 构建生产版本 |
| `npm run preview` | 预览生产构建(端口 10096 |
| `npm run preview` | 预览生产构建(端口 1219 |
| `npm run deploy` | 一键部署(安装依赖 + 构建) |
| `npm run start` | 一键启动(自动安装依赖 + 启动) |
| `npm run install-app` | 一键安装(从仓库安装到 /opt |

View File

@@ -1,7 +1,7 @@
#!/bin/bash
# QZMusic-Web 一键部署脚本
# 端口10096
# 端口1219
echo "=========================================="
echo " QZMusic-Web 一键部署"
@@ -59,5 +59,5 @@ echo "🚀 启动方式:"
echo " 开发模式: npm run dev"
echo " 预览模式: npm run preview"
echo ""
echo "🌐 访问地址: http://localhost:10096"
echo "🌐 访问地址: http://localhost:1219"
echo ""

View File

@@ -1,138 +1,206 @@
#!/bin/bash
# QZMusic-Web 一键安装脚本
# 从Gitea仓库获取并自动部署
# 使用方法: bash <(curl -sL http://171.80.3.149:4321/miao-moe/QZMusic-Web/raw/branch/master/install.sh)
# 或者直接运行此脚本
# 从 Gitea 仓库获取并自动部署,安装后以 systemd 服务对外暴露 1219 端口
# 使用方法:
# bash <(curl -sL http://171.80.3.149:4321/miao-moe/QZMusic-Web/raw/branch/master/install.sh)
# 或直接在项目目录运行: ./install.sh
set -e
echo "=========================================="
echo " QZMusic-Web 一键安装"
echo " QZMusic-Web 一键安装 (systemd)"
echo "=========================================="
echo ""
# 配置
# ========= 配置 =========
REPO_URL="http://171.80.3.149:4321/miao-moe/QZMusic-Web.git"
INSTALL_DIR="/opt/QZMusic-Web"
PORT=10096
PORT=1219
SERVICE_NAME="qzmusic-web"
BRANCH="master"
# 颜色定义
# ========= 颜色 =========
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m' # No Color
NC='\033[0m'
log_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# 检查是否以root运行
# ========= 权限 =========
SUDO=""
if [ "$EUID" -ne 0 ]; then
log_warn "建议使用 root 权限运行以获得最佳体验"
SUDO="sudo"
log_warn "当前非 root将使用 sudo 执行系统级操作。"
fi
# 检查Node.js
# ========= Node.js 检查 =========
if ! command -v node &> /dev/null; then
log_error "Node.js 未安装!请先安装 Node.js"
echo "安装 Node.js:"
echo " Ubuntu/Debian: sudo apt-get install nodejs npm"
echo " CentOS/RHEL: sudo yum install nodejs npm"
echo " 或访问: https://nodejs.org/"
log_error "Node.js 未安装!请先安装 Node.js (推荐 v18+)"
echo " Ubuntu/Debian: curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - && sudo apt-get install -y nodejs"
echo " CentOS/RHEL: curl -fsSL https://rpm.nodesource.com/setup_20.x | sudo bash - && sudo yum install -y nodejs"
exit 1
fi
log_info "Node.js 版本: $(node -v)"
log_info "npm 版本: $(npm -v)"
echo ""
# 检查是否已存在安装目录
# ========= 克隆/拉取代码 =========
if [ -d "$INSTALL_DIR" ]; then
log_warn "检测到已存在的安装目录: $INSTALL_DIR"
read -p "是否更新到最新版本?(y/n): " update_choice
if [ "$update_choice" != "y" ] && [ "$update_choice" != "Y" ]; then
log_info "取消安装"
exit 0
fi
log_info "正在更新到最新版本..."
cd "$INSTALL_DIR"
git pull origin master
if [ $? -ne 0 ]; then
log_error "更新失败!"
exit 1
if [ -d "$INSTALL_DIR/.git" ]; then
log_info "检测到已有 git 仓库,正在更新到最新版本..."
cd "$INSTALL_DIR"
git fetch origin "$BRANCH"
git reset --hard "origin/$BRANCH"
if [ $? -ne 0 ]; then
log_error "更新失败!"
exit 1
fi
else
log_warn "目录 $INSTALL_DIR 已存在但不是 git 仓库,将清理后重新克隆..."
$SUDO rm -rf "$INSTALL_DIR"
log_info "正在从仓库获取代码 ($REPO_URL)..."
$SUDO git clone -b "$BRANCH" "$REPO_URL" "$INSTALL_DIR"
$SUDO chown -R "$(whoami)" "$INSTALL_DIR" 2>/dev/null || true
fi
else
# 创建安装目录
log_info "正在创建安装目录: $INSTALL_DIR"
sudo mkdir -p "$INSTALL_DIR"
# 克隆仓库
log_info "正在从仓库获取代码..."
if ! git clone "$REPO_URL" "$INSTALL_DIR"; then
log_error "克隆仓库失败!"
exit 1
fi
$SUDO mkdir -p "$(dirname "$INSTALL_DIR")"
log_info "正在从仓库获取代码 ($REPO_URL)..."
$SUDO git clone -b "$BRANCH" "$REPO_URL" "$INSTALL_DIR"
$SUDO chown -R "$(whoami)" "$INSTALL_DIR" 2>/dev/null || true
fi
cd "$INSTALL_DIR"
echo ""
# 进入安装目录
cd "$INSTALL_DIR"
# 安装依赖
log_info "正在安装依赖..."
npm install --registry=https://registry.npmmirror.com
# ========= 安装依赖 =========
log_info "正在安装依赖 (使用淘宝镜像加速)..."
npm install --registry=https://registry.npmmirror.com --loglevel=error
if [ $? -ne 0 ]; then
log_error "依赖安装失败!"
exit 1
fi
log_info "依赖安装成功!"
echo ""
# 构建项目
# ========= 构建 =========
log_info "正在构建项目..."
npm run build
if [ $? -ne 0 ]; then
log_error "构建失败!"
exit 1
fi
log_info "项目构建成功!"
echo ""
# 检查端口占用
if lsof -Pi :$PORT -sTCP:LISTEN -t >/dev/null 2>&1; then
log_warn "端口 $PORT 已被占用,尝试停止现有进程..."
PID=$(lsof -ti:$PORT)
kill $PID 2>/dev/null || true
sleep 2
# ========= 部署 systemd 服务 =========
log_info "正在部署 systemd 服务: $SERVICE_NAME"
SERVICE_FILE="/etc/systemd/system/$SERVICE_NAME.service"
# 停止旧的监听(以防之前有进程占端口)
if command -v lsof &> /dev/null; then
OLD_PID=$(lsof -ti:$PORT 2>/dev/null || true)
if [ -n "$OLD_PID" ]; then
log_warn "端口 $PORT 已被占用 (PID: $OLD_PID),正在清理..."
$SUDO kill $OLD_PID 2>/dev/null || true
sleep 2
fi
fi
# 如果之前有同名服务,先停掉
if systemctl list-unit-files 2>/dev/null | grep -q "$SERVICE_NAME.service"; then
$SUDO systemctl stop "$SERVICE_NAME" 2>/dev/null || true
$SUDO systemctl disable "$SERVICE_NAME" 2>/dev/null || true
fi
# 写入服务文件
$SUDO tee "$SERVICE_FILE" > /dev/null <<EOF
[Unit]
Description=QZMusic Web Server
After=network.target
[Service]
Type=simple
WorkingDirectory=$INSTALL_DIR
ExecStart=$(command -v node) $INSTALL_DIR/server.cjs
Restart=always
RestartSec=3
Environment=NODE_ENV=production
Environment=QZMUSIC_PORT=$PORT
Environment=QZMUSIC_HOST=0.0.0.0
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
EOF
# 重载 & 启动
$SUDO systemctl daemon-reload
$SUDO systemctl enable "$SERVICE_NAME"
$SUDO systemctl restart "$SERVICE_NAME"
sleep 2
# ========= 防火墙开放 =========
log_info "正在开放防火墙端口 $PORT..."
if command -v firewall-cmd &> /dev/null && systemctl is-active --quiet firewalld 2>/dev/null; then
$SUDO firewall-cmd --permanent --add-port=${PORT}/tcp >/dev/null
$SUDO firewall-cmd --reload >/dev/null
log_info "firewalld: 已放行 $PORT/tcp"
elif command -v ufw &> /dev/null && systemctl is-active --quiet ufw 2>/dev/null; then
$SUDO ufw allow ${PORT}/tcp >/dev/null
log_info "ufw: 已放行 $PORT/tcp"
else
log_warn "未检测到活动的 firewalld/ufw跳过防火墙配置。如有其他防火墙请手动放行 $PORT/tcp。"
fi
# ========= 云服务器安全组提醒 =========
log_info "已处理系统防火墙。如果你的机器是云服务器,请记得在云厂商控制台的『安全组』也放行 $PORT/tcp。"
echo ""
# ========= 验证 =========
log_info "等待服务启动..."
for i in 1 2 3 4 5; do
if curl -s -o /dev/null -w "%{http_code}" "http://127.0.0.1:$PORT/" 2>/dev/null | grep -q "200"; then
break
fi
sleep 1
done
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" "http://127.0.0.1:$PORT/" 2>/dev/null || echo "000")
STATUS=$($SUDO systemctl is-active "$SERVICE_NAME" 2>/dev/null || echo "unknown")
# 获取本机公网/局域网 IP
LAN_IP=$(hostname -I 2>/dev/null | awk '{print $1}')
WAN_IP=$(curl -s --max-time 5 https://ifconfig.me 2>/dev/null || curl -s --max-time 5 https://api.ipify.org 2>/dev/null || echo "")
echo ""
echo "=========================================="
echo " 🎉 安装完成!"
echo "=========================================="
echo ""
echo "📂 安装目录: $INSTALL_DIR"
echo "🌐 访问地址: http://localhost:$PORT"
echo ""
echo "启动服务:"
echo " 开发模式: cd $INSTALL_DIR && npm run dev"
echo " 生产模式: cd $INSTALL_DIR && npm run preview"
echo "🖥 服务状态: $STATUS"
echo "🌐 本地访问: http://127.0.0.1:$PORT (HTTP $HTTP_CODE)"
if [ -n "$LAN_IP" ]; then
echo "🏠 局域网: http://$LAN_IP:$PORT"
fi
if [ -n "$WAN_IP" ]; then
echo "🌍 公网: http://$WAN_IP:$PORT"
fi
echo ""
echo "管理命令:"
echo " 更新: cd $INSTALL_DIR && git pull"
echo " 卸载: cd $INSTALL_DIR && npm run uninstall"
echo " 查看日志: sudo journalctl -u $SERVICE_NAME -f --since \"5 min ago\""
echo " 启动服务: sudo systemctl start $SERVICE_NAME"
echo " 停止服务: sudo systemctl stop $SERVICE_NAME"
echo " 重启服务: sudo systemctl restart $SERVICE_NAME"
echo " 开机自启: sudo systemctl enable $SERVICE_NAME"
echo " 更新代码: cd $INSTALL_DIR && git pull && npm run build && sudo systemctl restart $SERVICE_NAME"
echo ""
echo "卸载/清除所有部署: bash $INSTALL_DIR/uninstall.sh"
echo ""

View File

@@ -8,7 +8,7 @@
"scripts": {
"dev": "vite",
"build": "vue-tsc && vite build",
"preview": "vite preview --port 10096 --host",
"preview": "vite preview --port 1219 --host",
"serve": "node server.cjs",
"deploy": "./deploy.sh",
"start": "./start.sh",

18
qzmusic-web.service Normal file
View File

@@ -0,0 +1,18 @@
[Unit]
Description=QZMusic Web Server
After=network.target
[Service]
Type=simple
WorkingDirectory=/opt/QZMusic-Web
ExecStart=/usr/bin/env node server.cjs
Restart=always
RestartSec=3
Environment=NODE_ENV=production
Environment=QZMUSIC_PORT=1219
Environment=QZMUSIC_HOST=0.0.0.0
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target

View File

@@ -1,69 +1,119 @@
/**
* QZMusic Web 静态文件服务器
* 网访问支持
* QZMusic Web 静态文件服务器(生产用)
* 监听 0.0.0.0:1219支持公网访问
*/
const http = require('http');
const fs = require('fs');
const path = require('path');
const url = require('url');
const PORT = 10096;
const PORT = parseInt(process.env.QZMUSIC_PORT || '1219', 10);
const HOST = process.env.QZMUSIC_HOST || '0.0.0.0';
const ROOT = path.join(__dirname, 'dist');
const mimeTypes = {
'.html': 'text/html',
'.js': 'text/javascript',
'.css': 'text/css',
'.json': 'application/json',
'.png': 'image/png',
'.jpg': 'image/jpg',
'.gif': 'image/gif',
'.svg': 'image/svg+xml',
'.ico': 'image/x-icon',
'.ttf': 'font/ttf',
'.html': 'text/html; charset=utf-8',
'.htm': 'text/html; charset=utf-8',
'.js': 'application/javascript; charset=utf-8',
'.mjs': 'application/javascript; charset=utf-8',
'.css': 'text/css; charset=utf-8',
'.json': 'application/json; charset=utf-8',
'.png': 'image/png',
'.jpg': 'image/jpeg',
'.jpeg': 'image/jpeg',
'.gif': 'image/gif',
'.webp': 'image/webp',
'.svg': 'image/svg+xml',
'.ico': 'image/x-icon',
'.ttf': 'font/ttf',
'.woff': 'font/woff',
'.woff2': 'font/woff2'
'.woff2':'font/woff2',
'.map': 'application/json; charset=utf-8',
'.txt': 'text/plain; charset=utf-8'
};
function log(...args) {
const ts = new Date().toISOString().replace('T', ' ').substring(0, 19);
console.log(`[${ts}]`, ...args);
}
const server = http.createServer((req, res) => {
let filePath = path.join(ROOT, req.url === '/' ? 'index.html' : req.url);
const extname = String(path.extname(filePath)).toLowerCase();
const contentType = mimeTypes[extname] || 'application/octet-stream';
if (!extname && !fs.existsSync(filePath)) {
filePath = path.join(ROOT, 'index.html');
const parsed = url.parse(req.url);
let pathname = decodeURIComponent(parsed.pathname || '/');
if (pathname === '/') pathname = '/index.html';
let filePath = path.join(ROOT, pathname);
// 防止路径穿越
if (!filePath.startsWith(ROOT)) {
res.writeHead(403);
res.end('Forbidden');
return;
}
fs.readFile(filePath, (error, content) => {
if (error) {
if (error.code === 'ENOENT') {
fs.readFile(path.join(ROOT, 'index.html'), (err, html) => {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end(html, 'utf-8');
const extname = String(path.extname(filePath)).toLowerCase();
const contentType = mimeTypes[extname] || 'application/octet-stream';
// SPA 路由:如果不是带扩展名的文件且文件不存在,则回退到 index.html
const tryStatic = (cb) => {
fs.stat(filePath, (err, stat) => {
if (!err && stat.isDirectory()) {
filePath = path.join(filePath, 'index.html');
return fs.stat(filePath, (e2, s2) => {
if (!e2 && s2.isFile()) return cb(true);
return cb(false);
});
} else {
res.writeHead(500);
res.end('Sorry, check with the site admin for error: ' + error.code + ' ..\n');
}
} else {
res.writeHead(200, { 'Content-Type': contentType });
res.end(content, 'utf-8');
if (!err && stat.isFile()) return cb(true);
return cb(false);
});
};
tryStatic((found) => {
if (!found) {
filePath = path.join(ROOT, 'index.html');
}
fs.readFile(filePath, (error, content) => {
if (error) {
log(`${req.method} ${req.url} -> 500 (${error.code})`);
res.writeHead(500, { 'Content-Type': 'text/plain; charset=utf-8' });
res.end('Server Error: ' + error.code);
} else {
const finalType = found ? contentType : 'text/html; charset=utf-8';
res.writeHead(200, {
'Content-Type': finalType,
'Cache-Control': extname === '.html' || extname === '.htm'
? 'no-cache, no-store, must-revalidate'
: 'public, max-age=3600'
});
res.end(content);
log(`${req.method} ${req.url} -> 200 (${pathname})`);
}
});
});
});
server.listen(PORT, '0.0.0.0', () => {
console.log(`
╔═══════════════════════════════════════════════════════════════════════
║ QZMusic Web Server 启动成功!
本地访问:http://localhost:${PORT}
局域网访问http://[你的IP]:${PORT}
外网访问:请配置端口转发/公网IP访问
║ ║
╚═══════════════════════════════════════════════════════════════════════╝
`);
server.listen(PORT, HOST, () => {
const banner = `
╔══════════════════════════════════════════════════════════════╗
║ ║
║ QZMusic Web Server 启动成功! ║
║ ║
监听地址: http://${HOST}:${PORT}
本地访问: http://localhost:${PORT}
公网访问: http://[你的公网IP]:${PORT}
╚══════════════════════════════════════════════════════════════╝
`;
console.log(banner);
});
process.on('SIGINT', () => {
log('收到 SIGINT正在关闭服务器...');
server.close(() => process.exit(0));
});
process.on('SIGTERM', () => {
log('收到 SIGTERM正在关闭服务器...');
server.close(() => process.exit(0));
});

View File

@@ -1,7 +1,7 @@
#!/bin/bash
# QZMusic-Web 启动脚本
# 端口10096
# 端口1219
echo "=========================================="
echo " 启动 QZMusic-Web"
@@ -28,7 +28,7 @@ case ${choice:-2} in
1)
echo ""
echo "🚀 正在启动开发服务器..."
echo "🌐 访问地址: http://localhost:10096"
echo "🌐 访问地址: http://localhost:1219"
echo ""
echo "按 Ctrl+C 停止服务器"
echo ""
@@ -46,7 +46,7 @@ case ${choice:-2} in
fi
echo ""
echo "🚀 正在启动生产服务器..."
echo "🌐 访问地址: http://[你的IP]:10096"
echo "🌐 访问地址: http://[你的IP]:1219"
echo ""
echo "按 Ctrl+C 停止服务器"
echo ""

View File

@@ -1,109 +1,114 @@
#!/bin/bash
# QZMusic-Web 卸载脚本
# 完全删除所有QZMusic部署文件和配置
# QZMusic-Web 卸载脚本 - 完全停止并删除所有 QZMusic-Web 部署
set -e
echo "=========================================="
echo " QZMusic-Web 卸载工具"
echo " QZMusic-Web 完全卸载"
echo "=========================================="
echo ""
# 配置
# ========= 配置 =========
INSTALL_DIR="/opt/QZMusic-Web"
PORT=10096
PORT=1219
SERVICE_NAME="qzmusic-web"
# 颜色定义
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m'
log_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
SUDO=""
if [ "$EUID" -ne 0 ]; then
SUDO="sudo"
fi
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# 确认卸载
# ========= 确认 =========
echo "⚠️ 即将卸载 QZMusic-Web"
echo ""
read -p "确定要删除所有相关文件吗?(yes/no): " confirm
echo "将执行以下操作:"
echo " - 停止并禁用 systemd 服务 $SERVICE_NAME"
echo " - 删除服务文件 /etc/systemd/system/$SERVICE_NAME.service"
echo " - 杀掉占用 $PORT 端口的进程"
echo " - 删除目录 $INSTALL_DIR"
echo " - 关闭防火墙 $PORT/tcp 放行"
echo ""
read -p "确认删除?输入 yes 继续: " confirm
if [ "$confirm" != "yes" ]; then
log_info "取消卸载"
exit 0
fi
echo ""
# 停止服务
log_info "正在停止服务..."
# 停止开发服务器
PID=$(lsof -ti:$PORT 2>/dev/null || true)
if [ -n "$PID" ]; then
log_info "停止进程 (PID: $PID)..."
kill $PID 2>/dev/null || true
sleep 1
# ========= 停止服务 =========
log_info "停止 systemd 服务..."
if systemctl list-unit-files 2>/dev/null | grep -q "$SERVICE_NAME.service"; then
$SUDO systemctl stop "$SERVICE_NAME" 2>/dev/null || true
$SUDO systemctl disable "$SERVICE_NAME" 2>/dev/null || true
log_info "服务已停止 & 禁用"
else
log_warn "未检测到 systemd 服务 $SERVICE_NAME,跳过"
fi
# 停止Systemd服务如果存在
if systemctl is-active --quiet $SERVICE_NAME 2>/dev/null; then
log_info "停止 Systemd 服务..."
sudo systemctl stop $SERVICE_NAME
sudo systemctl disable $SERVICE_NAME
# ========= 删除服务文件 =========
SERVICE_FILE="/etc/systemd/system/$SERVICE_NAME.service"
if [ -f "$SERVICE_FILE" ]; then
$SUDO rm -f "$SERVICE_FILE"
$SUDO systemctl daemon-reload
log_info "已删除服务文件: $SERVICE_FILE"
fi
# 删除Systemd服务文件
if [ -f "/etc/systemd/system/$SERVICE_NAME.service" ]; then
log_info "删除 Systemd 服务文件..."
sudo rm -f /etc/systemd/system/$SERVICE_NAME.service
sudo systemctl daemon-reload
# ========= 杀端口 =========
if command -v lsof &> /dev/null; then
OLD_PID=$(lsof -ti:$PORT 2>/dev/null || true)
if [ -n "$OLD_PID" ]; then
log_info "杀掉占用 $PORT 的进程: $OLD_PID"
$SUDO kill $OLD_PID 2>/dev/null || true
fi
fi
echo ""
# 删除安装目录
# ========= 删除目录 =========
if [ -d "$INSTALL_DIR" ]; then
log_info "删除安装目录: $INSTALL_DIR"
sudo rm -rf "$INSTALL_DIR"
log_info "删除目录: $INSTALL_DIR"
$SUDO rm -rf "$INSTALL_DIR"
else
log_warn "目录不存在: $INSTALL_DIR"
fi
# 删除npm全局链接如果有
if npm list -g --depth=0 2>/dev/null | grep -q "qzmusic-web"; then
log_info "删除 npm 全局包..."
sudo npm uninstall -g qzmusic-web 2>/dev/null || true
# ========= 关闭防火墙端口 =========
log_info "关闭防火墙 $PORT/tcp 放行..."
if command -v firewall-cmd &> /dev/null && systemctl is-active --quiet firewalld 2>/dev/null; then
$SUDO firewall-cmd --permanent --remove-port=${PORT}/tcp >/dev/null 2>&1 || true
$SUDO firewall-cmd --reload >/dev/null
log_info "firewalld: 已关闭 $PORT/tcp"
elif command -v ufw &> /dev/null && systemctl is-active --quiet ufw 2>/dev/null; then
$SUDO ufw delete allow ${PORT}/tcp >/dev/null 2>&1 || true
log_info "ufw: 已关闭 $PORT/tcp"
else
log_warn "未检测到活动的 firewalld/ufw跳过防火墙配置。"
fi
# 删除相关缓存
log_info "清理缓存..."
# 删除npm缓存
# ========= 清理缓存 =========
log_info "清理 npm 缓存..."
if [ -d "$HOME/.npm/_cacache" ]; then
npm cache clean --force 2>/dev/null || true
npm cache clean --force >/dev/null 2>&1 || true
fi
# 删除可能的临时文件
sudo rm -rf /tmp/QZMusic* 2>/dev/null || true
sudo rm -rf /var/tmp/QZMusic* 2>/dev/null || true
$SUDO rm -rf /tmp/QZMusic* /var/tmp/QZMusic* 2>/dev/null || true
echo ""
echo "=========================================="
echo " ✅ 卸载完成!"
echo "=========================================="
echo ""
echo "已删除:"
echo " - 安装目录: $INSTALL_DIR"
echo " - 服务端口: $PORT"
echo "已清理:"
echo " - 目录: $INSTALL_DIR"
echo " - systemd 服务: $SERVICE_NAME"
echo " - 端口: $PORT"
echo " - 相关缓存"
echo ""
echo "如需重新安装,请运行:"

View File

@@ -21,7 +21,7 @@ export default defineConfig({
}
},
server: {
port: 10096,
port: 1219,
host: '0.0.0.0',
open: false
},