diff --git a/goldminer/.dockerignore b/goldminer/.dockerignore
new file mode 100644
index 00000000..2f0f04f9
--- /dev/null
+++ b/goldminer/.dockerignore
@@ -0,0 +1,21 @@
+.git
+.github
+.gitignore
+.DS_Store
+.env
+.env.*
+__pycache__
+*.pyc
+*.pyo
+*.pyd
+instance/
+.pytest_cache
+.coverage
+htmlcov/
+.vscode
+*.log
+logs/
+*.db
+tmp/
+node_modules/
+dist/
\ No newline at end of file
diff --git a/goldminer/.env.example b/goldminer/.env.example
new file mode 100644
index 00000000..d0b52d46
--- /dev/null
+++ b/goldminer/.env.example
@@ -0,0 +1,17 @@
+# ????
+FLASK_ENV=production
+PORT=8080
+
+# ?????
+DB_HOST=mysql2.sqlpub.com
+DB_PORT=3307
+DB_USER=goldminer
+DB_PASSWORD=nBAWq9DDwJ14Fugq
+DB_NAME=goldminer
+
+# ????
+SECRET_KEY=dev_key_for_goldminer
+ADMIN_SETUP_KEY=goldminer_admin_setup_key
+
+# ??
+TZ=Asia/Shanghai
diff --git a/goldminer/README.md b/goldminer/README.md
index 278c76e7..48520f82 100644
--- a/goldminer/README.md
+++ b/goldminer/README.md
@@ -1,203 +1,124 @@
-# 黄金矿工游戏
+# 黄金矿工游戏系统
-一个基于Vue和Flask的在线黄金矿工游戏,支持实时排行榜和玩家互动功能。
+黄金矿工是一个基于Web的多人在线游戏系统,使用Vue.js和Flask开发,支持Docker一键部署。
-## 项目结构
+## 项目特点
-- `frontend/`: Vue.js前端代码
-- `backend/`: Flask后端代码
-- `docker-compose.yml`: Docker编排配置文件
+- 经典黄金矿工游戏玩法
+- 实时排行榜和聊天系统
+- 用户账户系统
+- 完整的管理员后台
+- Docker化部署,便于安装和维护
-## 本地开发
+## 系统架构
-### 前端开发
+- **前端**:Vue.js、Socket.IO-client
+- **后端**:Flask、Flask-SocketIO、SQLAlchemy
+- **数据库**:MySQL
+- **部署**:Docker、Nginx
-```bash
-cd frontend
-npm install
-npm run serve
-```
+## 快速开始 (Docker)
-前端服务将运行在 http://localhost:8080
+### 环境要求
+- Docker
+- Docker Compose
-### 后端开发
+### 部署步骤
+1. 克隆仓库
```bash
-cd backend
-pip install -r requirements.txt
-python run_server.py
+git clone https://github.com/yourusername/goldminer.git
+cd goldminer
```
-后端服务将运行在 http://localhost:5000
-
-## Docker部署
+2. 启动服务 (Linux/Mac)
+```bash
+chmod +x start.sh
+./start.sh
+```
-项目已配置Docker支持,可以使用Docker Compose进行一键部署。
+Windows系统:
+```
+start.bat
+```
-### 前置条件
+3. 访问游戏
+ - 打开浏览器访问: http://localhost:8080
+ - 管理员初始账号: admin
+ - 管理员初始密码: admin
-- 安装 [Docker](https://www.docker.com/get-started)
-- 安装 [Docker Compose](https://docs.docker.com/compose/install/)
+### 环境变量配置
-### 运行步骤
+系统使用`.env`文件管理环境变量,首次运行会自动创建。主要配置项:
-1. 在项目根目录创建`.env`文件,配置环境变量(可选,已提供默认值):
+| 变量名 | 描述 | 默认值 |
+|--------|------|--------|
+| PORT | 前端服务端口 | 8080 |
+| 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_HOST=mysql2.sqlpub.com
-DB_PORT=3307
-DB_USER=goldminer
-DB_PASSWORD=nBAWq9DDwJ14Fugq
-DB_NAME=goldminer
-
-# 应用配置
-SECRET_KEY=dev_key_for_goldminer
-```
+## 手动开发环境搭建
-2. 使用Docker Compose构建和启动服务:
+### 后端开发
+1. 安装Python依赖
```bash
-docker-compose up -d
+cd backend
+pip install -r requirements.txt
+python run_server.py
```
-3. 访问应用:
- - 前端: http://localhost:8080
+2. 后端服务将在 http://localhost:5000 运行
-### 查看日志
+### 前端开发
+1. 安装依赖
```bash
-# 查看所有服务日志
-docker-compose logs
-
-# 查看特定服务日志
-docker-compose logs backend
-docker-compose logs frontend
+cd frontend
+npm install
```
-### 停止服务
-
+2. 启动开发服务器
```bash
-docker-compose down
+npm run serve
```
+3. 前端开发服务器将在 http://localhost:8080 运行
+
## 游戏功能
-- 登录和注册用户
-- 经典的黄金矿工游戏玩法
+- 用户注册与登录
+- 黄金矿工经典游戏玩法
- 实时排行榜
-- 在线玩家状态显示
- 游戏历史记录
-- 聊天室功能
-
-## 技术栈
-
-- 前端: Vue 3, Socket.io-client
-- 后端: Flask, Flask-SocketIO
-- 数据库: MySQL
-- 容器化: Docker, Docker Compose
-
-## 系统架构
-
-下图展示了黄金矿工游戏的系统架构:
-
-
-
-## 数据库配置
+- 实时聊天室
+- 管理后台
+ - 用户管理
+ - 排行榜管理
+ - 游戏历史管理
-本项目使用云端MySQL数据库存储用户数据、游戏记录和聊天信息。
+## 管理员功能
-数据库配置信息:
-- 数据库类型:MySQL 8.4.3
-- 服务提供商:SQLPub.com
-- 数据库名称:goldminer
-- 连接地址:mysql2.sqlpub.com:3307
+- 用户管理:查看、编辑、删除用户
+- 排行榜管理:查看、重置排行榜
+- 游戏历史管理:查看、删除游戏记录
-## 游戏说明
+## 生产环境部署
-- 使用鼠标点击或空格键发射绳索
-- 松开鼠标或空格键收回绳索
-- 按P键暂停游戏
-- 收集金块和钻石以获得分数
-- 达到目标分数进入下一关
-- 寻找特殊道具提升能力
-
-## 特殊道具
-
-- 速度提升:增加绳索伸缩速度
-- 磁力钩:增加抓取范围
-
-## 安装和运行
-
-### 快速启动(推荐)
-
-直接双击 `start.bat` 文件即可一键启动游戏。
-
-这个脚本会自动:
-1. 检查并安装所需的后端依赖
-2. 连接到云端数据库并创建必要的表(如果不存在)
-3. 同时启动后端和前端服务器
-4. 自动在浏览器中打开游戏
-
-### 手动启动
-
-如果自动脚本出现问题,可以按照以下步骤手动启动:
-
-#### 后端
-
-1. 进入后端目录
-```
-cd goldminer/backend
-```
-
-2. 安装依赖
-```
-pip install -r requirements.txt
-```
-
-3. 运行后端服务器
-```
-python app.py
-```
-
-服务器将在 http://localhost:5000 运行。
-
-#### 前端
-
-1. 进入前端目录
-```
-cd goldminer/frontend
-```
-
-2. 安装依赖
-```
-npm install
-```
-
-3. 开发模式运行
-```
-npm run serve
+1. 修改 `.env` 文件中的生产环境配置
+2. 启动Docker容器
+```bash
+docker compose up -d
```
-前端开发服务器将在 http://localhost:8080 运行。
-
-## 游戏说明
-
-- 使用鼠标点击或空格键发射绳索
-- 松开鼠标或空格键收回绳索
-- 按P键暂停游戏
-- 收集金块和钻石以获得分数
-- 达到目标分数进入下一关
-- 寻找特殊道具提升能力
-
-## 特殊道具
+## 开发者
-- 速度提升:增加绳索伸缩速度
-- 磁力钩:增加抓取范围
+- [Your Name]
-## 技术栈
+## 许可证
-- 后端:Flask, SQLAlchemy, PyMySQL
-- 前端:Vue 3
-- 数据库:MySQL 8.4.3 (云端)
-- 通信:Axios, Socket.IO
\ No newline at end of file
+MIT
\ No newline at end of file
diff --git a/goldminer/backend/Dockerfile b/goldminer/backend/Dockerfile
index d293a127..0ec1a640 100644
--- a/goldminer/backend/Dockerfile
+++ b/goldminer/backend/Dockerfile
@@ -2,6 +2,13 @@ FROM python:3.9-slim
WORKDIR /app
+# 安装系统依赖
+RUN apt-get update && apt-get install -y --no-install-recommends \
+ gcc \
+ python3-dev \
+ default-libmysqlclient-dev \
+ && rm -rf /var/lib/apt/lists/*
+
# 复制依赖文件
COPY requirements.txt .
@@ -14,6 +21,11 @@ COPY . .
# 设置环境变量
ENV PYTHONUNBUFFERED=1
ENV FLASK_APP=app.py
+ENV FLASK_ENV=production
+
+# 健康检查
+HEALTHCHECK --interval=30s --timeout=30s --start-period=5s --retries=3 \
+ CMD curl -f http://localhost:5000/api/health || exit 1
# 暴露端口
EXPOSE 5000
diff --git a/goldminer/backend/requirements.txt b/goldminer/backend/requirements.txt
index 5eadc6a9..d431fed6 100644
--- a/goldminer/backend/requirements.txt
+++ b/goldminer/backend/requirements.txt
@@ -1,7 +1,11 @@
-flask
-flask-cors
-flask-sqlalchemy
-flask-socketio
-werkzeug
-sqlalchemy<2.0.0
-pymysql
\ No newline at end of file
+flask==2.2.3
+flask-cors==3.0.10
+flask-sqlalchemy==2.5.1
+flask-socketio==5.3.2
+werkzeug==2.2.3
+sqlalchemy==1.4.46
+pymysql==1.0.3
+eventlet==0.33.3
+gunicorn==20.1.0
+python-dotenv==1.0.0
+mysqlclient==2.1.1
\ No newline at end of file
diff --git a/goldminer/backend/run_server.py b/goldminer/backend/run_server.py
index b6f25cc5..165863e0 100644
--- a/goldminer/backend/run_server.py
+++ b/goldminer/backend/run_server.py
@@ -1,23 +1,41 @@
-from app import app, socketio, init_db
import os
import logging
+from dotenv import load_dotenv
+from app import app, socketio, init_db
+
+# 加载环境变量
+load_dotenv()
# 配置日志
-logging.basicConfig(level=logging.INFO)
+logging.basicConfig(
+ level=logging.INFO,
+ format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
+)
logger = logging.getLogger(__name__)
if __name__ == '__main__':
# 在启动应用前初始化数据库
- init_db()
+ try:
+ init_db()
+ logger.info("数据库初始化成功")
+ except Exception as e:
+ logger.error(f"数据库初始化失败: {e}")
+ # 继续执行,因为可能会在应用启动后自动重试
# 从环境变量获取主机和端口,如果没有则使用默认值
host = os.environ.get('HOST', '0.0.0.0')
port = int(os.environ.get('PORT', 5000))
+ debug = os.environ.get('FLASK_ENV') == 'development'
+ logger.info(f"环境: {os.environ.get('FLASK_ENV', 'production')}")
logger.info(f"启动服务器,监听 {host}:{port}")
- logger.info(f"SECRET_KEY设置: {app.config['SECRET_KEY'][:5]}...")
- logger.info(f"SESSION_COOKIE_SECURE: {app.config['SESSION_COOKIE_SECURE']}")
- logger.info(f"CORS supports_credentials: True")
+ logger.info(f"SECRET_KEY已设置: {app.config['SECRET_KEY'][:3]}..." if 'SECRET_KEY' in app.config else "SECRET_KEY未设置")
+ logger.info(f"SESSION_COOKIE_SECURE: {app.config.get('SESSION_COOKIE_SECURE', False)}")
+ logger.info(f"CORS supports_credentials: {app.config.get('CORS_SUPPORTS_CREDENTIALS', False)}")
- # 启动应用,确保支持跨域会话
- socketio.run(app, host=host, port=port, allow_unsafe_werkzeug=True)
\ No newline at end of file
+ if debug:
+ logger.info("使用开发模式启动")
+ socketio.run(app, host=host, port=port, debug=True)
+ else:
+ logger.info("使用生产模式启动")
+ socketio.run(app, host=host, port=port, debug=False)
\ No newline at end of file
diff --git a/goldminer/docker-compose.yml b/goldminer/docker-compose.yml
index 995f8228..0a124757 100644
--- a/goldminer/docker-compose.yml
+++ b/goldminer/docker-compose.yml
@@ -5,12 +5,23 @@ services:
container_name: goldminer-backend
restart: always
environment:
+ - FLASK_ENV=${FLASK_ENV:-production}
- DB_HOST=${DB_HOST:-mysql2.sqlpub.com}
- DB_PORT=${DB_PORT:-3307}
- DB_USER=${DB_USER:-goldminer}
- DB_PASSWORD=${DB_PASSWORD:-nBAWq9DDwJ14Fugq}
- DB_NAME=${DB_NAME:-goldminer}
- SECRET_KEY=${SECRET_KEY:-dev_key_for_goldminer}
+ - ADMIN_SETUP_KEY=${ADMIN_SETUP_KEY:-goldminer_admin_setup_key}
+ - TZ=Asia/Shanghai
+ healthcheck:
+ test: ["CMD", "curl", "-f", "http://localhost:5000/api/health"]
+ interval: 30s
+ timeout: 10s
+ retries: 3
+ start_period: 40s
+ volumes:
+ - backend_logs:/app/logs
networks:
- app-network
@@ -25,10 +36,19 @@ services:
depends_on:
- backend
ports:
- - "8080:80"
+ - "${PORT:-8080}:80"
+ healthcheck:
+ test: ["CMD", "curl", "-f", "http://localhost:80/"]
+ interval: 30s
+ timeout: 10s
+ retries: 3
+ start_period: 40s
networks:
- app-network
+volumes:
+ backend_logs:
+
networks:
app-network:
driver: bridge
\ No newline at end of file
diff --git a/goldminer/frontend/Dockerfile b/goldminer/frontend/Dockerfile
index d7fb4076..86e16c14 100644
--- a/goldminer/frontend/Dockerfile
+++ b/goldminer/frontend/Dockerfile
@@ -5,22 +5,22 @@ WORKDIR /app
# 显示npm版本和node版本
RUN node -v && npm -v
-# 复制依赖文件
-COPY package*.json ./
+# 首先只复制包管理文件以利用缓存
+COPY package.json package-lock.json ./
-# 安装Vue CLI和项目依赖
-RUN npm install -g @vue/cli && npm install
+# 安装项目依赖
+RUN npm ci --quiet
# 复制所有前端源码
COPY . .
+# 设置生产环境构建
+ENV NODE_ENV=production
+
# 构建生产环境代码
-RUN echo "Building with vue-cli-service..." && \
- npx vue-cli-service build || \
- ./node_modules/.bin/vue-cli-service build || \
- vue-cli-service build
+RUN npm run build
-# 确保dist目录存在
+# 检查构建结果
RUN ls -la dist || exit 1
# 第二阶段:使用nginx提供静态文件
@@ -32,6 +32,11 @@ COPY --from=build-stage /app/dist /usr/share/nginx/html
# 复制自定义nginx配置
COPY nginx.conf /etc/nginx/conf.d/default.conf
+# 健康检查
+HEALTHCHECK --interval=30s --timeout=5s --start-period=5s --retries=3 \
+ CMD curl -f http://localhost:80/ || exit 1
+
+# 暴露端口
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
\ No newline at end of file
diff --git a/goldminer/frontend/nginx.conf b/goldminer/frontend/nginx.conf
index ed6367f2..e402a6c8 100644
--- a/goldminer/frontend/nginx.conf
+++ b/goldminer/frontend/nginx.conf
@@ -2,12 +2,27 @@ server {
listen 80;
server_name localhost;
+ # 安全设置
+ server_tokens off;
+ add_header X-Frame-Options "SAMEORIGIN" always;
+ add_header X-Content-Type-Options "nosniff" always;
+ add_header X-XSS-Protection "1; mode=block" always;
+ add_header Referrer-Policy "strict-origin-when-cross-origin" always;
+
root /usr/share/nginx/html;
index index.html;
+ # 设置文件缓存
+ location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
+ expires max;
+ add_header Cache-Control "public, max-age=31536000";
+ access_log off;
+ }
+
# 静态资源请求直接访问
location / {
try_files $uri $uri/ /index.html;
+ add_header Cache-Control "no-cache, no-store, must-revalidate";
}
# API请求代理到后端服务
@@ -17,6 +32,9 @@ server {
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;
+ proxy_read_timeout 90s;
+ proxy_connect_timeout 90s;
+ proxy_buffering off;
}
# Socket.IO请求代理到后端服务
@@ -29,8 +47,15 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_cache_bypass $http_upgrade;
+ proxy_read_timeout 86400s; # 设置更长的读取超时,适合WebSocket连接
+ proxy_buffering off;
}
+ # 压缩设置
+ gzip on;
+ gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
+ gzip_min_length 1000;
+
# 错误页面
error_page 404 /index.html;
error_page 500 502 503 504 /50x.html;
diff --git a/goldminer/frontend/node_modules/.cache/eslint/68c8e53b.json b/goldminer/frontend/node_modules/.cache/eslint/68c8e53b.json
index 3048cf4b..1cec4265 100644
--- a/goldminer/frontend/node_modules/.cache/eslint/68c8e53b.json
+++ b/goldminer/frontend/node_modules/.cache/eslint/68c8e53b.json
@@ -1 +1 @@
-[{"E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\main.js":"1","E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\router.js":"2","E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\App.vue":"3","E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\Register.vue":"4","E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\Login.vue":"5","E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\UserProfile.vue":"6","E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\ChatRoom.vue":"7","E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\Game.vue":"8","E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\Home.vue":"9","E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\Leaderboard.vue":"10","E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\Header.vue":"11","E:\\学习\\网络应用开发\\GM3\\Goldminer_new\\goldminer\\frontend\\src\\main.js":"12","E:\\学习\\网络应用开发\\GM3\\Goldminer_new\\goldminer\\frontend\\src\\router.js":"13","E:\\学习\\网络应用开发\\GM3\\Goldminer_new\\goldminer\\frontend\\src\\App.vue":"14","E:\\学习\\网络应用开发\\GM3\\Goldminer_new\\goldminer\\frontend\\src\\components\\Login.vue":"15","E:\\学习\\网络应用开发\\GM3\\Goldminer_new\\goldminer\\frontend\\src\\components\\Home.vue":"16","E:\\学习\\网络应用开发\\GM3\\Goldminer_new\\goldminer\\frontend\\src\\components\\UserProfile.vue":"17","E:\\学习\\网络应用开发\\GM3\\Goldminer_new\\goldminer\\frontend\\src\\components\\Register.vue":"18","E:\\学习\\网络应用开发\\GM3\\Goldminer_new\\goldminer\\frontend\\src\\components\\Game.vue":"19","E:\\学习\\网络应用开发\\GM3\\Goldminer_new\\goldminer\\frontend\\src\\components\\ChatRoom.vue":"20","E:\\学习\\网络应用开发\\GM3\\Goldminer_new\\goldminer\\frontend\\src\\components\\Leaderboard.vue":"21","E:\\学习\\网络应用开发\\GM3\\Goldminer_new\\goldminer\\frontend\\src\\components\\Header.vue":"22","E:\\学习\\网络应用开发\\GM3\\Goldminer_new\\goldminer\\frontend\\src\\components\\AdminSetup.vue":"23","E:\\学习\\网络应用开发\\GM3\\Goldminer_new\\goldminer\\frontend\\src\\components\\Admin.vue":"24"},{"size":420,"mtime":1750247900833,"results":"25","hashOfConfig":"26"},{"size":1555,"mtime":1750247900833,"results":"27","hashOfConfig":"26"},{"size":1004,"mtime":1750247900829,"results":"28","hashOfConfig":"26"},{"size":4492,"mtime":1750247900833,"results":"29","hashOfConfig":"26"},{"size":3472,"mtime":1750260439376,"results":"30","hashOfConfig":"26"},{"size":11652,"mtime":1750247900833,"results":"31","hashOfConfig":"26"},{"size":16278,"mtime":1750247900831,"results":"32","hashOfConfig":"26"},{"size":30598,"mtime":1750262074470,"results":"33","hashOfConfig":"26"},{"size":5735,"mtime":1750247900831,"results":"34","hashOfConfig":"26"},{"size":13225,"mtime":1750247900832,"results":"35","hashOfConfig":"26"},{"size":4152,"mtime":1750247900831,"results":"36","hashOfConfig":"26"},{"size":1538,"mtime":1750301139782,"results":"37","hashOfConfig":"38"},{"size":2525,"mtime":1750300541798,"results":"39","hashOfConfig":"38"},{"size":1004,"mtime":1750301895820,"results":"40","hashOfConfig":"38"},{"size":5227,"mtime":1750301071246,"results":"41","hashOfConfig":"38"},{"size":5735,"mtime":1750262863709,"results":"42","hashOfConfig":"38"},{"size":11652,"mtime":1750262863710,"results":"43","hashOfConfig":"38"},{"size":4492,"mtime":1750262863710,"results":"44","hashOfConfig":"38"},{"size":31688,"mtime":1750262863709,"results":"45","hashOfConfig":"38"},{"size":16278,"mtime":1750294243326,"results":"46","hashOfConfig":"38"},{"size":13225,"mtime":1750262863709,"results":"47","hashOfConfig":"38"},{"size":4675,"mtime":1750301706418,"results":"48","hashOfConfig":"38"},{"size":4836,"mtime":1750300463821,"results":"49","hashOfConfig":"38"},{"size":23162,"mtime":1750301706418,"results":"50","hashOfConfig":"38"},{"filePath":"51","messages":"52","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"53"},"1bydp2x",{"filePath":"54","messages":"55","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"53"},{"filePath":"56","messages":"57","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"58"},{"filePath":"59","messages":"60","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"58"},{"filePath":"61","messages":"62","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"63","messages":"64","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"58"},{"filePath":"65","messages":"66","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"58"},{"filePath":"67","messages":"68","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"69","messages":"70","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"58"},{"filePath":"71","messages":"72","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"58"},{"filePath":"73","messages":"74","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"58"},{"filePath":"75","messages":"76","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"77"},"1s9qeh2",{"filePath":"78","messages":"79","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"77"},{"filePath":"80","messages":"81","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"82","messages":"83","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"84"},{"filePath":"85","messages":"86","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"84"},{"filePath":"87","messages":"88","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"84"},{"filePath":"89","messages":"90","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"84"},{"filePath":"91","messages":"92","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"84"},{"filePath":"93","messages":"94","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"84"},{"filePath":"95","messages":"96","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"84"},{"filePath":"97","messages":"98","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"84"},{"filePath":"99","messages":"100","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"84"},{"filePath":"101","messages":"102","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"84"},"E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\main.js",[],[],"E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\router.js",[],"E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\App.vue",[],[],"E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\Register.vue",[],"E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\Login.vue",[],"E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\UserProfile.vue",[],"E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\ChatRoom.vue",[],"E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\Game.vue",[],"E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\Home.vue",[],"E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\Leaderboard.vue",[],"E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\Header.vue",[],"E:\\学习\\网络应用开发\\GM3\\Goldminer_new\\goldminer\\frontend\\src\\main.js",[],[],"E:\\学习\\网络应用开发\\GM3\\Goldminer_new\\goldminer\\frontend\\src\\router.js",[],"E:\\学习\\网络应用开发\\GM3\\Goldminer_new\\goldminer\\frontend\\src\\App.vue",[],"E:\\学习\\网络应用开发\\GM3\\Goldminer_new\\goldminer\\frontend\\src\\components\\Login.vue",[],[],"E:\\学习\\网络应用开发\\GM3\\Goldminer_new\\goldminer\\frontend\\src\\components\\Home.vue",[],"E:\\学习\\网络应用开发\\GM3\\Goldminer_new\\goldminer\\frontend\\src\\components\\UserProfile.vue",[],"E:\\学习\\网络应用开发\\GM3\\Goldminer_new\\goldminer\\frontend\\src\\components\\Register.vue",[],"E:\\学习\\网络应用开发\\GM3\\Goldminer_new\\goldminer\\frontend\\src\\components\\Game.vue",[],"E:\\学习\\网络应用开发\\GM3\\Goldminer_new\\goldminer\\frontend\\src\\components\\ChatRoom.vue",[],"E:\\学习\\网络应用开发\\GM3\\Goldminer_new\\goldminer\\frontend\\src\\components\\Leaderboard.vue",[],"E:\\学习\\网络应用开发\\GM3\\Goldminer_new\\goldminer\\frontend\\src\\components\\Header.vue",[],"E:\\学习\\网络应用开发\\GM3\\Goldminer_new\\goldminer\\frontend\\src\\components\\AdminSetup.vue",[],"E:\\学习\\网络应用开发\\GM3\\Goldminer_new\\goldminer\\frontend\\src\\components\\Admin.vue",[]]
\ No newline at end of file
+[{"E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\main.js":"1","E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\router.js":"2","E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\App.vue":"3","E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\Register.vue":"4","E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\Login.vue":"5","E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\UserProfile.vue":"6","E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\ChatRoom.vue":"7","E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\Game.vue":"8","E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\Home.vue":"9","E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\Leaderboard.vue":"10","E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\Header.vue":"11","E:\\学习\\网络应用开发\\GM3\\Goldminer_new\\goldminer\\frontend\\src\\main.js":"12","E:\\学习\\网络应用开发\\GM3\\Goldminer_new\\goldminer\\frontend\\src\\router.js":"13","E:\\学习\\网络应用开发\\GM3\\Goldminer_new\\goldminer\\frontend\\src\\App.vue":"14","E:\\学习\\网络应用开发\\GM3\\Goldminer_new\\goldminer\\frontend\\src\\components\\Login.vue":"15","E:\\学习\\网络应用开发\\GM3\\Goldminer_new\\goldminer\\frontend\\src\\components\\Home.vue":"16","E:\\学习\\网络应用开发\\GM3\\Goldminer_new\\goldminer\\frontend\\src\\components\\UserProfile.vue":"17","E:\\学习\\网络应用开发\\GM3\\Goldminer_new\\goldminer\\frontend\\src\\components\\Register.vue":"18","E:\\学习\\网络应用开发\\GM3\\Goldminer_new\\goldminer\\frontend\\src\\components\\Game.vue":"19","E:\\学习\\网络应用开发\\GM3\\Goldminer_new\\goldminer\\frontend\\src\\components\\ChatRoom.vue":"20","E:\\学习\\网络应用开发\\GM3\\Goldminer_new\\goldminer\\frontend\\src\\components\\Leaderboard.vue":"21","E:\\学习\\网络应用开发\\GM3\\Goldminer_new\\goldminer\\frontend\\src\\components\\Header.vue":"22","E:\\学习\\网络应用开发\\GM3\\Goldminer_new\\goldminer\\frontend\\src\\components\\AdminSetup.vue":"23","E:\\学习\\网络应用开发\\GM3\\Goldminer_new\\goldminer\\frontend\\src\\components\\Admin.vue":"24"},{"size":420,"mtime":1750247900833,"results":"25","hashOfConfig":"26"},{"size":1555,"mtime":1750247900833,"results":"27","hashOfConfig":"26"},{"size":1004,"mtime":1750247900829,"results":"28","hashOfConfig":"26"},{"size":4492,"mtime":1750247900833,"results":"29","hashOfConfig":"26"},{"size":3472,"mtime":1750260439376,"results":"30","hashOfConfig":"26"},{"size":11652,"mtime":1750247900833,"results":"31","hashOfConfig":"26"},{"size":16278,"mtime":1750247900831,"results":"32","hashOfConfig":"26"},{"size":30598,"mtime":1750262074470,"results":"33","hashOfConfig":"26"},{"size":5735,"mtime":1750247900831,"results":"34","hashOfConfig":"26"},{"size":13225,"mtime":1750247900832,"results":"35","hashOfConfig":"26"},{"size":4152,"mtime":1750247900831,"results":"36","hashOfConfig":"26"},{"size":1538,"mtime":1750301139782,"results":"37","hashOfConfig":"38"},{"size":2525,"mtime":1750300541798,"results":"39","hashOfConfig":"38"},{"size":1004,"mtime":1750301895820,"results":"40","hashOfConfig":"38"},{"size":5105,"mtime":1750317486368,"results":"41","hashOfConfig":"38"},{"size":5735,"mtime":1750262863709,"results":"42","hashOfConfig":"38"},{"size":11652,"mtime":1750262863710,"results":"43","hashOfConfig":"38"},{"size":4492,"mtime":1750262863710,"results":"44","hashOfConfig":"38"},{"size":31688,"mtime":1750262863709,"results":"45","hashOfConfig":"38"},{"size":16278,"mtime":1750294243326,"results":"46","hashOfConfig":"38"},{"size":13225,"mtime":1750262863709,"results":"47","hashOfConfig":"38"},{"size":4675,"mtime":1750301706418,"results":"48","hashOfConfig":"38"},{"size":4836,"mtime":1750302859806,"results":"49","hashOfConfig":"38"},{"size":23162,"mtime":1750301706418,"results":"50","hashOfConfig":"38"},{"filePath":"51","messages":"52","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"53"},"1bydp2x",{"filePath":"54","messages":"55","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"53"},{"filePath":"56","messages":"57","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"58"},{"filePath":"59","messages":"60","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"58"},{"filePath":"61","messages":"62","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"63","messages":"64","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"58"},{"filePath":"65","messages":"66","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"58"},{"filePath":"67","messages":"68","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"69","messages":"70","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"58"},{"filePath":"71","messages":"72","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"58"},{"filePath":"73","messages":"74","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"58"},{"filePath":"75","messages":"76","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"77"},"1s9qeh2",{"filePath":"78","messages":"79","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"77"},{"filePath":"80","messages":"81","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"82"},{"filePath":"83","messages":"84","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"85","messages":"86","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"82"},{"filePath":"87","messages":"88","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"82"},{"filePath":"89","messages":"90","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"82"},{"filePath":"91","messages":"92","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"82"},{"filePath":"93","messages":"94","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"82"},{"filePath":"95","messages":"96","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"82"},{"filePath":"97","messages":"98","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"82"},{"filePath":"99","messages":"100","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"101","messages":"102","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0,"usedDeprecatedRules":"82"},"E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\main.js",[],[],"E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\router.js",[],"E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\App.vue",[],[],"E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\Register.vue",[],"E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\Login.vue",[],"E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\UserProfile.vue",[],"E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\ChatRoom.vue",[],"E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\Game.vue",[],"E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\Home.vue",[],"E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\Leaderboard.vue",[],"E:\\学习\\网络应用开发\\Goldminer\\Goldminer_new\\goldminer\\frontend\\src\\components\\Header.vue",[],"E:\\学习\\网络应用开发\\GM3\\Goldminer_new\\goldminer\\frontend\\src\\main.js",[],[],"E:\\学习\\网络应用开发\\GM3\\Goldminer_new\\goldminer\\frontend\\src\\router.js",[],"E:\\学习\\网络应用开发\\GM3\\Goldminer_new\\goldminer\\frontend\\src\\App.vue",[],[],"E:\\学习\\网络应用开发\\GM3\\Goldminer_new\\goldminer\\frontend\\src\\components\\Login.vue",[],"E:\\学习\\网络应用开发\\GM3\\Goldminer_new\\goldminer\\frontend\\src\\components\\Home.vue",[],"E:\\学习\\网络应用开发\\GM3\\Goldminer_new\\goldminer\\frontend\\src\\components\\UserProfile.vue",[],"E:\\学习\\网络应用开发\\GM3\\Goldminer_new\\goldminer\\frontend\\src\\components\\Register.vue",[],"E:\\学习\\网络应用开发\\GM3\\Goldminer_new\\goldminer\\frontend\\src\\components\\Game.vue",[],"E:\\学习\\网络应用开发\\GM3\\Goldminer_new\\goldminer\\frontend\\src\\components\\ChatRoom.vue",[],"E:\\学习\\网络应用开发\\GM3\\Goldminer_new\\goldminer\\frontend\\src\\components\\Leaderboard.vue",[],"E:\\学习\\网络应用开发\\GM3\\Goldminer_new\\goldminer\\frontend\\src\\components\\Header.vue",[],"E:\\学习\\网络应用开发\\GM3\\Goldminer_new\\goldminer\\frontend\\src\\components\\AdminSetup.vue",[],"E:\\学习\\网络应用开发\\GM3\\Goldminer_new\\goldminer\\frontend\\src\\components\\Admin.vue",[]]
\ No newline at end of file
diff --git a/goldminer/frontend/src/components/Admin.vue b/goldminer/frontend/src/components/Admin.vue
new file mode 100644
index 00000000..77bd9646
--- /dev/null
+++ b/goldminer/frontend/src/components/Admin.vue
@@ -0,0 +1,816 @@
+
+
+
管理控制台
+
+
+
+
+
+
+
+
+
+
+
用户管理
+
+
+
+
+
+
+
+
+
+
+
+
+
+
排行榜管理
+
+
+
+
+
+
+
+
+ 排名 |
+ 用户名 |
+ 最高分 |
+ 最后游戏 |
+ 操作 |
+
+
+
+
+ {{ index + 1 }} |
+ {{ user.username }} |
+ {{ user.high_score }} |
+ {{ formatDate(user.last_login) }} |
+
+
+
+ |
+
+
+
+
+
+
+
+
+
游戏历史管理
+
+
+
+
+
+
+
+
+
+ ID |
+ 用户 |
+ 分数 |
+ 等级 |
+ 时长(秒) |
+ 金币 |
+ 游戏时间 |
+ 操作 |
+
+
+
+
+ {{ record.id }} |
+ {{ record.username }} |
+ {{ record.score }} |
+ {{ record.level_reached }} |
+ {{ record.duration }} |
+ {{ record.gold_earned }} |
+ {{ formatDate(record.created_at) }} |
+
+
+ |
+
+
+
+
+
+
+
+
+
+
{{ confirmDialogTitle }}
+
{{ confirmDialogMessage }}
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/goldminer/frontend/src/components/AdminSetup.vue b/goldminer/frontend/src/components/AdminSetup.vue
new file mode 100644
index 00000000..fa5443a1
--- /dev/null
+++ b/goldminer/frontend/src/components/AdminSetup.vue
@@ -0,0 +1,226 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/goldminer/frontend/src/components/Login.vue b/goldminer/frontend/src/components/Login.vue
index 464b9645..4e2e74a0 100644
--- a/goldminer/frontend/src/components/Login.vue
+++ b/goldminer/frontend/src/components/Login.vue
@@ -2,9 +2,6 @@