优化游戏界面

main
wang 2 months ago committed by 李冠威
parent 1bedce8fb8
commit c2ff1817f9

@ -17,49 +17,88 @@
- **数据库**MySQL
- **部署**Docker、Nginx
## 快速开始 (Docker)
## Docker部署说明
本项目已完全支持Docker部署只需几个简单的步骤即可运行
### 环境要求
- Docker
- Docker Compose
- Docker 20.10+
- Docker Compose 2.0+
### 部署步骤
1. 克隆仓库
1. 克隆项目代码:
```bash
git clone https://github.com/yourusername/goldminer.git
git clone <仓库地址>
cd goldminer
```
2. 启动服务 (Linux/Mac)
2. 创建环境配置文件(可选):
```bash
chmod +x start.sh
./start.sh
```
# 复制示例配置
cp .env.example .env
Windows系统:
# 根据需要编辑配置
nano .env # 或使用其他编辑器
```
3. 启动服务:
```bash
# Windows用户
start.bat
# Linux/Mac用户
bash start.sh
```
3. 访问游戏
- 打开浏览器访问: http://localhost:8080
- 管理员初始账号: admin
- 管理员初始密码: admin
或者手动启动:
### 环境变量配置
```bash
# 构建并启动容器
docker-compose up -d --build
```
4. 访问服务:
- 前端网页http://localhost:8080
- 管理员初始账号admin
- 管理员初始密码admin
### 环境变量说明
系统使用`.env`文件管理环境变量,首次运行会自动创建。主要配置项:
可以通过创建`.env`文件或设置环境变量来自定义配置:
| 变量名 | 描述 | 默认值 |
| 变量名 | 说明 | 默认值 |
|--------|------|--------|
| PORT | 前端服务端口 | 8080 |
| DB_HOST | 数据库主机名 | mysql2.sqlpub.com |
| PORT | 网站访问端口 | 8080 |
| FLASK_ENV | Flask环境 | production |
| DB_HOST | 数据库主机 | mysql2.sqlpub.com |
| DB_PORT | 数据库端口 | 3307 |
| DB_USER | 数据库用户名 | goldminer |
| DB_PASSWORD | 数据库密码 | nBAWq9DDwJ14Fugq |
| SECRET_KEY | Flask会话密钥 | dev_key_for_goldminer |
| ADMIN_SETUP_KEY | 管理员初始化密钥 | goldminer_admin_setup_key |
| DB_NAME | 数据库名称 | goldminer |
| SECRET_KEY | 应用密钥 | dev_key_for_goldminer |
| ADMIN_SETUP_KEY | 管理员设置密钥 | goldminer_admin_setup_key |
### 常见问题排查
1. 如果无法访问前端页面,请检查:
- 确认容器是否正常运行:`docker-compose ps`
- 查看前端日志:`docker-compose logs frontend`
- 检查端口是否被占用:`netstat -ano | findstr 8080`
2. 如果图片资源无法显示:
- 确认项目根目录下是否存在`images`文件夹
- 确保`images`文件夹中包含必要的图片资源
- 查看nginx日志`docker-compose logs frontend`
3. 如果后端API无法连接
- 检查后端服务是否正常:`docker-compose logs backend`
- 确认数据库连接信息是否正确
## 手动开发环境搭建

@ -7,6 +7,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
gcc \
python3-dev \
default-libmysqlclient-dev \
curl \
&& rm -rf /var/lib/apt/lists/*
# 复制依赖文件
@ -15,6 +16,9 @@ COPY requirements.txt .
# 安装依赖
RUN pip install --no-cache-dir -r requirements.txt
# 创建日志目录
RUN mkdir -p /app/logs && chmod 777 /app/logs
# 复制所有后端源码
COPY . .

@ -37,6 +37,8 @@ services:
- backend
ports:
- "${PORT:-8080}:80"
volumes:
- ./images:/usr/share/nginx/html/images
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:80/"]
interval: 30s

@ -14,6 +14,12 @@ RUN npm ci --quiet
# 复制所有前端源码
COPY . .
# 确保images目录存在于public目录中
RUN if [ ! -d "public/images" ] && [ -d "../images" ]; then \
mkdir -p public/images && \
cp -r ../images/* public/images/; \
fi
# 设置生产环境构建
ENV NODE_ENV=production
@ -26,9 +32,16 @@ RUN ls -la dist || exit 1
# 第二阶段使用nginx提供静态文件
FROM nginx:stable-alpine AS production-stage
# 安装curl用于健康检查
RUN apk add --no-cache curl
# 从构建阶段复制构建结果到nginx默认目录
COPY --from=build-stage /app/dist /usr/share/nginx/html
# 创建images目录并确保权限正确
RUN mkdir -p /usr/share/nginx/html/images && \
chmod -R 755 /usr/share/nginx/html
# 复制自定义nginx配置
COPY nginx.conf /etc/nginx/conf.d/default.conf

@ -9,6 +9,11 @@ server {
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# 允许跨域访问
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE' always;
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization' always;
root /usr/share/nginx/html;
index index.html;
@ -19,6 +24,15 @@ server {
access_log off;
}
# 特别处理images目录
location /images/ {
alias /usr/share/nginx/html/images/;
autoindex off;
expires max;
add_header Cache-Control "public, max-age=31536000";
try_files $uri $uri/ =404;
}
# 静态资源请求直接访问
location / {
try_files $uri $uri/ /index.html;

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

@ -1,115 +1,3 @@
<template>
<div class="admin-container">
<h1>管理控制台</h1>
@ -179,9 +67,6 @@
:disabled="currentUser && currentUser.id === user.id">
删除
</button>
<button @click="resetUserScore(user.id)" class="reset-btn">
重置分数
</button>
</td>
</tr>
</tbody>
@ -222,44 +107,6 @@
</div>
</div>
<!-- 排行榜管理 -->
<div v-if="activeTab === 'leaderboard'" class="tab-content">
<h2>排行榜管理</h2>
<div class="leaderboard-actions">
<button @click="confirmResetAllScores" class="danger-btn">
重置所有分数
</button>
</div>
<div class="table-wrapper">
<table class="leaderboard-table">
<thead>
<tr>
<th>排名</th>
<th>用户名</th>
<th>最高分</th>
<th>最后游戏</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="(user, index) in leaderboard" :key="user.id">
<td>{{ index + 1 }}</td>
<td>{{ user.username }}</td>
<td>{{ user.high_score }}</td>
<td>{{ formatDate(user.last_login) }}</td>
<td class="actions">
<button @click="editUser(user)" class="edit-btn">编辑</button>
<button @click="resetUserScore(user.id)" class="reset-btn">
重置分数
</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<!-- 游戏历史管理 -->
<div v-if="activeTab === 'history'" class="tab-content">
<h2>游戏历史管理</h2>
@ -334,7 +181,6 @@ export default {
activeTab: 'users',
tabs: [
{ id: 'users', name: '用户管理' },
{ id: 'leaderboard', name: '排行榜管理' },
{ id: 'history', name: '游戏历史' }
],
@ -343,9 +189,6 @@ export default {
filteredUsers: [],
userSearchTerm: '',
//
leaderboard: [],
//
gameHistory: [],
filteredGameHistory: [],
@ -441,7 +284,6 @@ export default {
await Promise.all([
this.loadUsers(),
this.loadLeaderboard(),
this.loadGameHistory()
])
},
@ -472,59 +314,6 @@ export default {
this.loadUsers()
},
//
async loadLeaderboard() {
try {
const response = await axios.get('/api/leaderboard')
this.leaderboard = response.data.leaderboard
} catch (error) {
console.error('加载排行榜失败:', error)
}
},
async confirmResetAllScores() {
this.showConfirmDialog = true
this.confirmDialogTitle = '重置所有分数'
this.confirmDialogMessage = '确定要重置所有用户的分数吗?此操作不可撤销!'
this.confirmDialogAction = this.resetAllScores
},
async resetAllScores() {
try {
await axios.post('/api/admin/leaderboard/reset')
this.showConfirmDialog = false
//
await this.loadUsers()
await this.loadLeaderboard()
await this.loadGameHistory()
alert('所有分数已重置')
} catch (error) {
console.error('重置分数失败:', error)
alert('重置分数失败: ' + (error.response?.data?.error || '未知错误'))
}
},
async resetUserScore(userId) {
this.showConfirmDialog = true
this.confirmDialogTitle = '重置用户分数'
this.confirmDialogMessage = '确定要重置此用户的分数吗?此操作不可撤销!'
this.confirmDialogAction = async () => {
try {
await axios.post('/api/admin/leaderboard/reset', { user_id: userId })
this.showConfirmDialog = false
//
await this.loadUsers()
await this.loadLeaderboard()
await this.loadGameHistory()
alert('用户分数已重置')
} catch (error) {
console.error('重置分数失败:', error)
alert('重置分数失败: ' + (error.response?.data?.error || '未知错误'))
}
}
},
//
async loadGameHistory() {
try {
@ -595,7 +384,6 @@ export default {
//
await this.loadUsers()
await this.loadLeaderboard()
// localStorage
const userData = JSON.parse(localStorage.getItem('user'))
@ -656,7 +444,6 @@ export default {
//
await this.loadUsers()
await this.loadLeaderboard()
await this.loadGameHistory()
alert('用户已删除')
@ -784,7 +571,7 @@ tr:hover {
gap: 5px;
}
.edit-btn, .delete-btn, .reset-btn, .refresh-btn {
.edit-btn, .delete-btn, .refresh-btn {
padding: 5px 8px;
border: none;
border-radius: 3px;
@ -802,11 +589,6 @@ tr:hover {
color: white;
}
.reset-btn {
background-color: #ff9800;
color: white;
}
.refresh-btn {
background-color: #2196F3;
color: white;

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

@ -1,81 +1,142 @@
@echo off
setlocal enabledelayedexpansion
title Gold Miner Game Launcher
echo ==== 黄金矿工游戏系统部署脚本 ====
echo 正在检查环境...
REM Process command line arguments
if "%1"=="1" goto backend_direct
if "%1"=="2" goto frontend_direct
:: 检查Docker是否安装
docker --version > nul 2>&1
if %errorlevel% neq 0 (
echo 错误: 未检测到Docker. 请安装Docker后再运行此脚本.
pause
exit /b
:menu
cls
echo ===================================
echo Gold Miner Game Launcher
echo ===================================
echo.
echo Current computer IP address:
ipconfig | find "IPv4"
echo.
echo Please note the IP address shown above. Other computers can access the game using this address.
echo Other computers should use http://[your-IP-address]:8080 to access the game.
echo.
echo Please select an option:
echo [1] Start Backend Server
echo [2] Start Frontend Server
echo [3] Start Both Frontend and Backend (Two Windows)
echo [4] Exit
echo.
set /p choice=Enter your choice (1-4):
if "%choice%"=="1" goto backend
if "%choice%"=="2" goto frontend
if "%choice%"=="3" goto both
if "%choice%"=="4" goto end
echo Invalid option, please try again.
timeout /t 2 >nul
goto menu
:backend_direct
REM Start backend directly from command line
title Gold Miner - Backend Server
goto backend_start
:backend
cls
echo ===================================
echo Starting Backend Server
echo ===================================
echo.
:backend_start
cd /d %~dp0
REM Activate virtual environment if it exists
if exist "..\..\.venv\Scripts\activate.bat" (
call "..\..\.venv\Scripts\activate.bat"
echo Virtual environment activated
)
:: 检查Docker Compose是否安装
docker compose version > nul 2>&1
if %errorlevel% neq 0 (
echo 错误: 未检测到Docker Compose. 请安装Docker Compose后再运行此脚本.
REM Check backend dependencies
echo Installing backend dependencies...
cd backend
python -m pip install -r requirements.txt
REM Run the backend server with host=0.0.0.0
echo ===================================
echo Starting Backend Server...
echo Backend will listen on all network interfaces (0.0.0.0:5000)
echo Connecting to cloud database: mysql2.sqlpub.com:3307
echo ===================================
python app.py
pause
if "%1"=="" goto menu
exit /b
)
echo Docker环境检查通过!
:: 检查.env文件是否存在不存在则从示例文件创建
if not exist ".env" (
echo 未发现.env文件, 从示例创建...
if exist ".env.example" (
copy .env.example .env
echo 已创建.env文件. 请检查并根据需要修改配置.
) else (
echo 错误: 未找到.env.example文件. 正在创建基本配置...
echo # 应用配置> .env
echo FLASK_ENV=production>> .env
echo PORT=8080>> .env
echo.>> .env
echo # 数据库配置>> .env
echo DB_HOST=mysql2.sqlpub.com>> .env
echo DB_PORT=3307>> .env
echo DB_USER=goldminer>> .env
echo DB_PASSWORD=nBAWq9DDwJ14Fugq>> .env
echo DB_NAME=goldminer>> .env
echo.>> .env
echo # 安全配置>> .env
echo SECRET_KEY=dev_key_for_goldminer>> .env
echo ADMIN_SETUP_KEY=goldminer_admin_setup_key>> .env
echo.>> .env
echo # 时区>> .env
echo TZ=Asia/Shanghai>> .env
)
)
:frontend_direct
REM Start frontend directly from command line
title Gold Miner - Frontend Server
goto frontend_start
:: 构建并启动容器
echo 正在构建并启动容器...
docker compose down
docker compose build --no-cache
docker compose up -d
:: 检查容器是否成功启动
timeout /t 5 /nobreak > nul
docker compose ps | find "goldminer-backend" > nul
if %errorlevel% neq 0 (
echo 错误: 容器未能成功启动. 请查看日志排查问题:
docker compose logs
:frontend
cls
echo ===================================
echo Starting Frontend Server
echo ===================================
echo.
:frontend_start
cd /d %~dp0
REM Switch to frontend directory
cd frontend
echo Current directory: %cd%
REM Check if npm is installed
where npm >nul 2>nul
if %ERRORLEVEL% NEQ 0 (
echo Error: npm not found. Please install Node.js
pause
exit /b
goto menu
)
:: 获取端口号
set PORT=8080
for /f "tokens=1,2 delims==" %%a in (.env) do (
if "%%a"=="PORT" set PORT=%%b
)
REM Install dependencies
echo Installing frontend dependencies...
call npm install
call npm install vue-router@4 axios --save
echo ==== 黄金矿工游戏系统已成功部署! ====
echo 前端访问地址: http://localhost:%PORT%
echo 管理员初始账号: admin
echo 管理员初始密码: admin
echo.
echo 提示: 按任意键退出,系统将继续在后台运行
REM Run the frontend server with host=0.0.0.0
echo ===================================
echo Starting Frontend Server...
echo Frontend will listen on all network interfaces (0.0.0.0:8080)
echo ===================================
echo Local access URL: http://localhost:8080
echo LAN access URL: http://[your-IP-address]:8080
echo ===================================
call npm run serve -- --host 0.0.0.0
pause
if "%1"=="" goto menu
exit /b
:both
cls
echo ===================================
echo Starting Both Frontend and Backend Servers
echo ===================================
echo.
echo Two windows will open to run frontend and backend servers separately.
echo Do not close either window until you want to stop the game.
echo.
echo Press any key to continue...
pause >nul
REM Start backend in a new window
start cmd /k "%~f0" 1
REM Start frontend in a new window
start cmd /k "%~f0" 2
goto menu
:end
echo Thank you for using Gold Miner Game Launcher!
timeout /t 2 >nul
exit /b 0

@ -1,55 +0,0 @@
#!/bin/bash
# 设置颜色变量
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
echo -e "${GREEN}==== 黄金矿工游戏系统部署脚本 ====${NC}"
echo -e "${YELLOW}正在检查环境...${NC}"
# 检查Docker是否安装
if ! [ -x "$(command -v docker)" ]; then
echo -e "${RED}错误: 未检测到Docker. 请安装Docker后再运行此脚本.${NC}" >&2
exit 1
fi
# 检查Docker Compose是否安装
if ! [ -x "$(command -v docker compose)" ]; then
echo -e "${RED}错误: 未检测到Docker Compose. 请安装Docker Compose后再运行此脚本.${NC}" >&2
exit 1
fi
echo -e "${GREEN}Docker环境检查通过!${NC}"
# 检查.env文件是否存在不存在则从示例文件创建
if [ ! -f ".env" ]; then
echo -e "${YELLOW}未发现.env文件, 从示例创建...${NC}"
if [ -f ".env.example" ]; then
cp .env.example .env
echo -e "${BLUE}已创建.env文件. 请检查并根据需要修改配置.${NC}"
else
echo -e "${RED}错误: 未找到.env.example文件. 无法创建配置.${NC}" >&2
exit 1
fi
fi
# 构建并启动容器
echo -e "${GREEN}正在构建并启动容器...${NC}"
docker compose down
docker compose build --no-cache
docker compose up -d
# 检查容器是否成功启动
sleep 5
if [ "$(docker compose ps -q | wc -l)" -eq 2 ]; then
echo -e "${GREEN}==== 黄金矿工游戏系统已成功部署! ====${NC}"
echo -e "${BLUE}前端访问地址: http://localhost:$(grep PORT .env | cut -d= -f2 || echo 8080)${NC}"
echo -e "${BLUE}管理员初始账号: admin${NC}"
echo -e "${BLUE}管理员初始密码: admin${NC}"
else
echo -e "${RED}错误: 容器未能成功启动. 请查看日志排查问题:${NC}"
docker compose logs
fi
Loading…
Cancel
Save