feat: 项目初始化及当前全部内容提交
This commit is contained in:
@@ -0,0 +1 @@
|
||||
900d585f575b1619e74296496e2fe22f2c2e71b6ad8901d7cab82634765cc10d emotion-museum-1.0.0-20250713_111829.tar.gz
|
||||
Binary file not shown.
@@ -0,0 +1,171 @@
|
||||
# 情绪博物馆测试环境配置文件
|
||||
# 请根据实际部署环境修改相应配置
|
||||
|
||||
# ================================
|
||||
# 基础环境配置
|
||||
# ================================
|
||||
ENVIRONMENT=test
|
||||
SERVER_IP=localhost
|
||||
DEPLOY_PATH=/data/emotion-museum
|
||||
|
||||
# ================================
|
||||
# 数据库配置
|
||||
# ================================
|
||||
MYSQL_HOST=localhost
|
||||
MYSQL_PORT=3306
|
||||
MYSQL_ROOT_PASSWORD=123456
|
||||
MYSQL_DATABASE=emotion_museum
|
||||
MYSQL_USERNAME=emotion
|
||||
MYSQL_PASSWORD=emotion123
|
||||
|
||||
# Nacos数据库配置
|
||||
NACOS_DATABASE=nacos_config
|
||||
|
||||
# ================================
|
||||
# Redis配置
|
||||
# ================================
|
||||
REDIS_HOST=localhost
|
||||
REDIS_PORT=6379
|
||||
REDIS_PASSWORD=
|
||||
|
||||
# ================================
|
||||
# Nacos配置
|
||||
# ================================
|
||||
NACOS_SERVER_ADDR=localhost:8848
|
||||
NACOS_NAMESPACE=emotion-test
|
||||
NACOS_GROUP=TEST_GROUP
|
||||
NACOS_USERNAME=nacos
|
||||
NACOS_PASSWORD=nacos
|
||||
|
||||
# ================================
|
||||
# 服务端口配置
|
||||
# ================================
|
||||
GATEWAY_PORT=9000
|
||||
USER_SERVICE_PORT=9001
|
||||
AI_SERVICE_PORT=9002
|
||||
WEB_PORT=3000
|
||||
NGINX_PORT=80
|
||||
NGINX_HTTPS_PORT=443
|
||||
|
||||
# ================================
|
||||
# JWT配置
|
||||
# ================================
|
||||
JWT_SECRET=emotion-museum-test-secret-key-2025
|
||||
JWT_EXPIRATION=7200
|
||||
JWT_REFRESH_EXPIRATION=86400
|
||||
|
||||
# ================================
|
||||
# COZE AI配置
|
||||
# ================================
|
||||
COZE_API_TOKEN=your-coze-api-token
|
||||
COZE_BOT_ID=7523042446285439016
|
||||
COZE_WORKFLOW_ID=7523047462895796287
|
||||
COZE_API_BASE_URL=https://api.coze.cn
|
||||
|
||||
# ================================
|
||||
# 文件存储配置
|
||||
# ================================
|
||||
UPLOAD_PATH=/data/uploads/emotion-museum
|
||||
UPLOAD_MAX_SIZE=10485760
|
||||
LOG_PATH=/data/logs/emotion-museum
|
||||
|
||||
# ================================
|
||||
# 前端配置
|
||||
# ================================
|
||||
VUE_APP_API_BASE_URL=http://localhost:9000
|
||||
VUE_APP_GATEWAY_URL=http://localhost:9000
|
||||
VUE_APP_WS_URL=ws://localhost:9000/ws
|
||||
VUE_APP_TITLE=情绪博物馆 - 测试环境
|
||||
VUE_APP_ENVIRONMENT=test
|
||||
VUE_APP_ENABLE_DEBUG=true
|
||||
|
||||
# ================================
|
||||
# Docker配置
|
||||
# ================================
|
||||
DOCKER_REGISTRY=
|
||||
DOCKER_NAMESPACE=emotion-museum
|
||||
DOCKER_TAG=test-latest
|
||||
|
||||
# ================================
|
||||
# 监控配置
|
||||
# ================================
|
||||
ENABLE_PROMETHEUS=true
|
||||
ENABLE_GRAFANA=false
|
||||
PROMETHEUS_PORT=9090
|
||||
GRAFANA_PORT=3001
|
||||
|
||||
# ================================
|
||||
# 安全配置
|
||||
# ================================
|
||||
ENABLE_HTTPS=false
|
||||
SSL_CERT_PATH=/etc/nginx/ssl
|
||||
ENABLE_RATE_LIMIT=true
|
||||
ENABLE_FIREWALL=false
|
||||
|
||||
# ================================
|
||||
# 备份配置
|
||||
# ================================
|
||||
BACKUP_PATH=/data/backups/emotion-museum
|
||||
BACKUP_RETENTION_DAYS=7
|
||||
AUTO_BACKUP_ENABLED=true
|
||||
BACKUP_SCHEDULE="0 2 * * *"
|
||||
|
||||
# ================================
|
||||
# 日志配置
|
||||
# ================================
|
||||
LOG_LEVEL=INFO
|
||||
LOG_MAX_SIZE=100MB
|
||||
LOG_MAX_HISTORY=30
|
||||
ENABLE_LOG_ROTATION=true
|
||||
|
||||
# ================================
|
||||
# 缓存配置
|
||||
# ================================
|
||||
CACHE_DEFAULT_TTL=3600
|
||||
CACHE_USER_INFO_TTL=1800
|
||||
CACHE_CONVERSATION_TTL=7200
|
||||
|
||||
# ================================
|
||||
# 限流配置
|
||||
# ================================
|
||||
RATE_LIMIT_ENABLED=true
|
||||
RATE_LIMIT_DEFAULT_LIMIT=100
|
||||
RATE_LIMIT_DEFAULT_WINDOW=60
|
||||
|
||||
# ================================
|
||||
# 健康检查配置
|
||||
# ================================
|
||||
HEALTH_CHECK_INTERVAL=30
|
||||
HEALTH_CHECK_TIMEOUT=10
|
||||
HEALTH_CHECK_RETRIES=3
|
||||
|
||||
# ================================
|
||||
# 性能配置
|
||||
# ================================
|
||||
JVM_XMS=512m
|
||||
JVM_XMX=1024m
|
||||
JVM_XMN=256m
|
||||
HIKARI_MINIMUM_IDLE=3
|
||||
HIKARI_MAXIMUM_POOL_SIZE=15
|
||||
|
||||
# ================================
|
||||
# 开发调试配置
|
||||
# ================================
|
||||
DEBUG_ENABLED=true
|
||||
LOG_REQUESTS=true
|
||||
LOG_RESPONSES=false
|
||||
MOCK_ENABLED=false
|
||||
SAMPLE_DATA_ENABLED=true
|
||||
|
||||
# ================================
|
||||
# 网络配置
|
||||
# ================================
|
||||
NETWORK_NAME=emotion-test-network
|
||||
SUBNET=172.20.0.0/16
|
||||
GATEWAY_IP=172.20.0.1
|
||||
|
||||
# ================================
|
||||
# 时区配置
|
||||
# ================================
|
||||
TZ=Asia/Shanghai
|
||||
TIMEZONE=GMT+8
|
||||
@@ -0,0 +1,471 @@
|
||||
# 情绪博物馆测试环境部署指南
|
||||
|
||||
## 📋 概述
|
||||
|
||||
本文档提供了情绪博物馆项目测试环境的完整部署方案,包括环境安装、数据库初始化、服务部署等全流程。
|
||||
|
||||
**新版本特性**:
|
||||
- ✅ 支持IP访问,暂不使用域名
|
||||
- ✅ 自动化环境安装 (Java, Maven, Node.js, Docker等)
|
||||
- ✅ 自动化数据库初始化 (MySQL + Nacos)
|
||||
- ✅ 测试环境专用配置
|
||||
- ✅ 使用最新稳定版本软件
|
||||
- ✅ 完整的健康检查和监控
|
||||
|
||||
## 🏗️ 架构说明
|
||||
|
||||
### 服务组件
|
||||
- **前端应用** (Vue3 + Ant Design) - 端口: 3000 → 80 (Nginx)
|
||||
- **API网关** (Spring Cloud Gateway) - 端口: 9000
|
||||
- **AI服务** (Spring Boot + Coze API) - 端口: 9002
|
||||
- **用户服务** (Spring Boot) - 端口: 9001
|
||||
- **MySQL数据库** - 端口: 3306
|
||||
- **Redis缓存** - 端口: 6379
|
||||
- **Nacos注册中心** - 端口: 8848
|
||||
- **Nginx反向代理** - 端口: 80
|
||||
|
||||
### 网络架构
|
||||
```
|
||||
用户 → Nginx(80) → 前端(3000) / API网关(9000) → 微服务 → 数据库
|
||||
↓
|
||||
Nacos注册中心(8848)
|
||||
```
|
||||
|
||||
## 🚀 快速开始
|
||||
|
||||
### 1. 系统要求
|
||||
- **操作系统**: Linux/macOS (推荐 Ubuntu 20.04+)
|
||||
- **内存**: 最少4GB,推荐8GB+
|
||||
- **磁盘**: 最少20GB可用空间
|
||||
- **网络**: 能够访问互联网
|
||||
|
||||
### 2. 一键部署
|
||||
```bash
|
||||
# 进入部署目录
|
||||
cd emotion-museum-1.0.0-20250713_111829
|
||||
|
||||
# 一键部署(包含环境安装、数据库初始化、服务部署)
|
||||
chmod +x deploy.sh
|
||||
./deploy.sh
|
||||
```
|
||||
|
||||
### 3. 分步部署
|
||||
```bash
|
||||
# 1. 安装基础环境
|
||||
./deploy.sh install-env
|
||||
|
||||
# 2. 初始化数据库
|
||||
./deploy.sh init-db
|
||||
|
||||
# 3. 构建应用镜像
|
||||
./deploy.sh build
|
||||
|
||||
# 4. 启动服务
|
||||
./deploy.sh start
|
||||
```
|
||||
|
||||
### 4. 访问应用
|
||||
- **前端应用**: http://localhost
|
||||
- **API网关**: http://localhost:9000
|
||||
- **Nacos控制台**: http://localhost:8848/nacos (nacos/nacos)
|
||||
- **Nacos控制台**: http://localhost:8848/nacos (nacos/nacos)
|
||||
|
||||
## 📁 文件结构
|
||||
|
||||
```
|
||||
emotion-museum-1.0.0-20250713_111829/
|
||||
├── deploy.sh # 主部署脚本
|
||||
├── install-environment.sh # 环境安装脚本
|
||||
├── init-database.sh # 数据库初始化脚本
|
||||
├── manage.sh # 服务管理脚本
|
||||
├── docker-compose.yml # 默认配置
|
||||
├── docker-compose.test.yml # 测试环境配置
|
||||
├── .env.test # 测试环境变量
|
||||
├── README.md # 快速开始指南
|
||||
├── DEPLOY.md # 详细部署文档
|
||||
├── backend/ # 后端服务
|
||||
│ ├── emotion-gateway-1.0.0.jar
|
||||
│ ├── emotion-user-1.0.0.jar
|
||||
│ ├── emotion-ai-1.0.0.jar
|
||||
│ ├── gateway-Dockerfile
|
||||
│ ├── user-Dockerfile
|
||||
│ ├── ai-Dockerfile
|
||||
│ └── config/ # 配置文件
|
||||
│ ├── application-test.yml
|
||||
│ ├── gateway-test.yml
|
||||
│ └── ai-test.yml
|
||||
├── frontend/ # 前端应用
|
||||
│ ├── Dockerfile
|
||||
│ ├── nginx.conf
|
||||
│ ├── index.html
|
||||
│ ├── assets/
|
||||
│ └── config/
|
||||
│ └── test.env.js
|
||||
├── database/ # 数据库脚本
|
||||
│ ├── mysql_emotion_museum_final.sql
|
||||
│ └── verify-database-script.sql
|
||||
└── deploy/ # 部署配置
|
||||
├── nginx/conf.d/
|
||||
├── mysql/conf.d/
|
||||
└── redis/
|
||||
```
|
||||
|
||||
## ⚙️ 配置说明
|
||||
|
||||
### 环境变量配置
|
||||
|
||||
编辑 `.env.test` 文件:
|
||||
|
||||
```bash
|
||||
# 服务器IP(重要:请修改为实际IP)
|
||||
SERVER_IP=localhost
|
||||
|
||||
# 数据库配置
|
||||
MYSQL_HOST=localhost
|
||||
MYSQL_PORT=3306
|
||||
MYSQL_ROOT_PASSWORD=123456
|
||||
MYSQL_USERNAME=emotion
|
||||
MYSQL_PASSWORD=emotion123
|
||||
|
||||
# Redis配置
|
||||
REDIS_HOST=localhost
|
||||
REDIS_PORT=6379
|
||||
|
||||
# Nacos配置
|
||||
NACOS_SERVER_ADDR=localhost:8848
|
||||
|
||||
# COZE AI配置(重要:请配置实际的API Token)
|
||||
COZE_API_TOKEN=your-coze-api-token
|
||||
|
||||
# JWT配置
|
||||
JWT_SECRET=emotion-museum-test-secret-key-2025
|
||||
|
||||
# 时区设置
|
||||
TZ=Asia/Shanghai
|
||||
```
|
||||
|
||||
### 服务配置
|
||||
|
||||
- **网关配置**: `backend/config/gateway-test.yml`
|
||||
- **用户服务配置**: `backend/config/application-test.yml`
|
||||
- **AI服务配置**: `backend/config/ai-test.yml`
|
||||
- **前端配置**: `frontend/config/test.env.js`
|
||||
|
||||
### 数据库配置
|
||||
|
||||
- **MySQL配置**: `deploy/mysql/conf.d/my.cnf`
|
||||
- **Redis配置**: `deploy/redis/redis.conf`
|
||||
- **初始化脚本**: `database/mysql_emotion_museum_final.sql`
|
||||
|
||||
## 🛠️ 管理命令
|
||||
|
||||
### 部署命令
|
||||
|
||||
```bash
|
||||
# 完整部署(推荐)
|
||||
./deploy.sh
|
||||
|
||||
# 分步部署
|
||||
./deploy.sh install-env # 安装环境
|
||||
./deploy.sh init-db # 初始化数据库
|
||||
./deploy.sh build # 构建镜像
|
||||
./deploy.sh start # 启动服务
|
||||
|
||||
# 跳过某些步骤
|
||||
./deploy.sh --skip-env # 跳过环境安装
|
||||
./deploy.sh --skip-db # 跳过数据库初始化
|
||||
./deploy.sh --debug # 启用调试模式
|
||||
```
|
||||
|
||||
### 服务管理
|
||||
|
||||
```bash
|
||||
# 查看服务状态
|
||||
./deploy.sh status
|
||||
|
||||
# 启动服务
|
||||
./deploy.sh start
|
||||
|
||||
# 停止服务
|
||||
./deploy.sh stop
|
||||
|
||||
# 重启服务
|
||||
./deploy.sh restart
|
||||
|
||||
# 重启特定服务
|
||||
./deploy.sh restart gateway
|
||||
./deploy.sh restart user-service
|
||||
./deploy.sh restart ai-service
|
||||
```
|
||||
|
||||
### 日志管理
|
||||
|
||||
```bash
|
||||
# 查看所有服务日志
|
||||
./deploy.sh logs
|
||||
|
||||
# 跟踪日志输出
|
||||
./deploy.sh logs -f
|
||||
|
||||
# 查看特定服务日志
|
||||
./deploy.sh logs gateway
|
||||
./deploy.sh logs user-service
|
||||
./deploy.sh logs ai-service
|
||||
```
|
||||
|
||||
### 数据管理
|
||||
|
||||
```bash
|
||||
# 备份数据
|
||||
./deploy.sh backup
|
||||
|
||||
# 健康检查
|
||||
./deploy.sh health
|
||||
|
||||
# 更新服务
|
||||
./deploy.sh update
|
||||
|
||||
# 清理资源
|
||||
./deploy.sh clean
|
||||
```
|
||||
|
||||
### 独立脚本
|
||||
|
||||
```bash
|
||||
# 环境安装
|
||||
./install-environment.sh
|
||||
|
||||
# 数据库初始化
|
||||
./init-database.sh
|
||||
|
||||
# 服务管理(兼容旧版本)
|
||||
./manage.sh start
|
||||
./manage.sh stop
|
||||
./manage.sh status
|
||||
```
|
||||
|
||||
## 🔧 生产环境配置
|
||||
|
||||
### 1. 修改环境配置
|
||||
|
||||
复制并修改环境配置文件:
|
||||
|
||||
```bash
|
||||
# 复制测试环境配置
|
||||
cp .env.test .env.prod
|
||||
|
||||
# 修改生产环境配置
|
||||
vim .env.prod
|
||||
```
|
||||
|
||||
关键配置项:
|
||||
|
||||
```bash
|
||||
# 修改为实际服务器IP
|
||||
SERVER_IP=your-server-ip
|
||||
|
||||
# 修改为生产环境数据库密码
|
||||
MYSQL_ROOT_PASSWORD=your-strong-password
|
||||
MYSQL_PASSWORD=your-strong-password
|
||||
|
||||
# 配置实际的COZE API Token
|
||||
COZE_API_TOKEN=your-actual-coze-api-token
|
||||
|
||||
# 配置强密码的JWT密钥
|
||||
JWT_SECRET=your-production-jwt-secret-key
|
||||
|
||||
# 启用HTTPS(如需要)
|
||||
ENABLE_HTTPS=true
|
||||
NGINX_HTTPS_PORT=443
|
||||
```
|
||||
|
||||
### 2. 域名和SSL配置(可选)
|
||||
|
||||
如果需要使用域名和HTTPS:
|
||||
|
||||
```bash
|
||||
# 放置SSL证书
|
||||
mkdir -p deploy/nginx/ssl
|
||||
cp your-domain.crt deploy/nginx/ssl/
|
||||
cp your-domain.key deploy/nginx/ssl/
|
||||
|
||||
# 修改Nginx配置
|
||||
vim deploy/nginx/conf.d/default.conf
|
||||
```
|
||||
|
||||
### 3. 防火墙配置
|
||||
|
||||
```bash
|
||||
# Ubuntu/Debian
|
||||
sudo ufw allow 80/tcp
|
||||
sudo ufw allow 443/tcp
|
||||
|
||||
# CentOS/RHEL
|
||||
sudo firewall-cmd --permanent --add-port=80/tcp
|
||||
sudo firewall-cmd --permanent --add-port=443/tcp
|
||||
sudo firewall-cmd --reload
|
||||
```
|
||||
|
||||
## 📊 监控和维护
|
||||
|
||||
### 服务监控
|
||||
|
||||
```bash
|
||||
# 查看服务状态
|
||||
./deploy.sh status
|
||||
|
||||
# 健康检查
|
||||
./deploy.sh health
|
||||
|
||||
# 资源使用情况
|
||||
docker stats
|
||||
|
||||
# 查看容器状态
|
||||
docker ps -a
|
||||
```
|
||||
|
||||
### 日志管理
|
||||
|
||||
```bash
|
||||
# 查看应用日志
|
||||
./deploy.sh logs
|
||||
|
||||
# 查看特定服务日志
|
||||
./deploy.sh logs gateway
|
||||
./deploy.sh logs user-service
|
||||
./deploy.sh logs ai-service
|
||||
|
||||
# 实时跟踪日志
|
||||
./deploy.sh logs -f
|
||||
|
||||
# 查看系统日志
|
||||
tail -f /data/logs/emotion-museum/gateway-service.log
|
||||
tail -f /data/logs/emotion-museum/user-service.log
|
||||
```
|
||||
|
||||
### 性能优化
|
||||
|
||||
1. **JVM参数调整**:修改 `.env.test` 中的JVM配置
|
||||
2. **数据库优化**:调整 `deploy/mysql/conf.d/my.cnf`
|
||||
3. **Redis优化**:调整 `deploy/redis/redis.conf`
|
||||
4. **Nginx优化**:调整 `deploy/nginx/conf.d/default.conf`
|
||||
|
||||
## 🔒 安全配置
|
||||
|
||||
### 1. 数据库安全
|
||||
- 修改默认密码
|
||||
- 限制访问IP
|
||||
- 启用SSL连接
|
||||
|
||||
### 2. Redis安全
|
||||
- 设置密码认证
|
||||
- 绑定特定IP
|
||||
- 禁用危险命令
|
||||
|
||||
### 3. Nginx安全
|
||||
- 启用HTTPS
|
||||
- 配置安全头
|
||||
- 限制请求频率
|
||||
|
||||
### 4. 应用安全
|
||||
- 配置JWT密钥
|
||||
- 启用CORS限制
|
||||
- 设置API限流
|
||||
|
||||
## 🚨 故障排除
|
||||
|
||||
### 常见问题
|
||||
|
||||
#### 1. 环境安装失败
|
||||
|
||||
```bash
|
||||
# 检查系统要求
|
||||
./install-environment.sh verify
|
||||
|
||||
# 手动安装特定组件
|
||||
./install-environment.sh java
|
||||
./install-environment.sh docker
|
||||
```
|
||||
|
||||
#### 2. 数据库初始化失败
|
||||
|
||||
```bash
|
||||
# 检查MySQL容器状态
|
||||
docker logs emotion-mysql
|
||||
|
||||
# 重新初始化数据库
|
||||
./init-database.sh clean
|
||||
./init-database.sh
|
||||
```
|
||||
|
||||
#### 3. 服务启动失败
|
||||
|
||||
```bash
|
||||
# 查看服务日志
|
||||
./deploy.sh logs service-name
|
||||
|
||||
# 检查端口占用
|
||||
netstat -tlnp | grep :port
|
||||
|
||||
# 重启服务
|
||||
./deploy.sh restart service-name
|
||||
```
|
||||
|
||||
#### 4. 网络连接问题
|
||||
|
||||
```bash
|
||||
# 检查Docker网络
|
||||
docker network ls
|
||||
docker network inspect emotion-test-network
|
||||
|
||||
# 检查服务健康状态
|
||||
./deploy.sh health
|
||||
```
|
||||
|
||||
#### 5. 配置文件问题
|
||||
|
||||
```bash
|
||||
# 检查环境变量
|
||||
cat .env.test
|
||||
|
||||
# 验证配置文件语法
|
||||
docker-compose -f docker-compose.test.yml config
|
||||
```
|
||||
|
||||
### 性能问题
|
||||
|
||||
1. **内存不足**:调整 `.env.test` 中的JVM参数
|
||||
2. **磁盘空间不足**:清理Docker资源 `./deploy.sh clean`
|
||||
3. **网络延迟**:检查服务间网络连接
|
||||
|
||||
### 日志分析
|
||||
|
||||
```bash
|
||||
# 查看详细部署日志
|
||||
./deploy.sh --debug
|
||||
|
||||
# 查看容器启动日志
|
||||
docker logs emotion-gateway
|
||||
docker logs emotion-mysql
|
||||
docker logs emotion-nacos
|
||||
```
|
||||
|
||||
## 📞 技术支持
|
||||
|
||||
如遇到问题,请按以下步骤排查:
|
||||
|
||||
1. **查看日志**:`./deploy.sh logs --debug`
|
||||
2. **检查状态**:`./deploy.sh status`
|
||||
3. **验证配置**:检查 `.env.test` 配置
|
||||
4. **重新部署**:`./deploy.sh clean && ./deploy.sh`
|
||||
|
||||
## 📝 注意事项
|
||||
|
||||
- ⚠️ **首次部署**:请确保修改 `.env.test` 中的 `SERVER_IP` 和 `COZE_API_TOKEN`
|
||||
- ⚠️ **生产环境**:请修改所有默认密码和密钥
|
||||
- ⚠️ **防火墙**:确保开放必要的端口 (80, 3306, 6379, 8848, 9000-9002)
|
||||
- ⚠️ **资源要求**:确保服务器有足够的内存和磁盘空间
|
||||
|
||||
---
|
||||
|
||||
**部署完成后,请及时修改默认密码和配置文件中的敏感信息!**
|
||||
@@ -0,0 +1,210 @@
|
||||
# 情绪博物馆快速部署指南
|
||||
|
||||
## 📦 包内容说明
|
||||
|
||||
```
|
||||
emotion-museum-1.0.0-YYYYMMDD_HHMMSS/
|
||||
├── frontend/ # 前端构建产物
|
||||
│ ├── dist/ # 静态文件
|
||||
│ ├── Dockerfile # 前端容器配置
|
||||
│ └── nginx.conf # Nginx配置
|
||||
├── backend/ # 后端JAR文件
|
||||
│ ├── emotion-gateway-*.jar # 网关服务
|
||||
│ ├── emotion-ai-*.jar # AI服务
|
||||
│ ├── emotion-user-*.jar # 用户服务
|
||||
│ ├── config/ # 配置文件
|
||||
│ └── *-Dockerfile # 各服务容器配置
|
||||
├── database/ # 数据库脚本
|
||||
│ └── mysql_emotion_museum_final.sql
|
||||
├── deploy/ # 部署配置
|
||||
│ ├── nginx/ # Nginx配置
|
||||
│ ├── mysql/ # MySQL配置
|
||||
│ └── redis/ # Redis配置
|
||||
├── docker-compose.yml # 开发环境配置
|
||||
├── docker-compose.prod.yml # 生产环境配置
|
||||
├── deploy.sh # 部署脚本
|
||||
├── quick-deploy.sh # 快速部署脚本
|
||||
├── manage.sh # 管理脚本
|
||||
├── .env # 环境变量模板
|
||||
├── VERSION.txt # 版本信息
|
||||
├── DEPLOY.md # 详细部署文档
|
||||
└── QUICK_START.md # 本文件
|
||||
```
|
||||
|
||||
## 🚀 快速部署步骤
|
||||
|
||||
### 1. 系统要求
|
||||
- **操作系统**: Linux/macOS/Windows
|
||||
- **Docker**: 20.10+
|
||||
- **Docker Compose**: 1.29+
|
||||
- **内存**: 最少4GB,推荐8GB+
|
||||
- **磁盘**: 最少10GB可用空间
|
||||
|
||||
### 2. 部署步骤
|
||||
|
||||
#### 方式一:一键部署(推荐)
|
||||
```bash
|
||||
# 1. 解压部署包
|
||||
tar -xzf emotion-museum-*.tar.gz
|
||||
cd emotion-museum-*
|
||||
|
||||
# 2. 配置环境变量
|
||||
cp .env .env.local
|
||||
vim .env.local # 编辑配置,特别是COZE_API_TOKEN
|
||||
|
||||
# 3. 一键部署
|
||||
chmod +x quick-deploy.sh
|
||||
./quick-deploy.sh
|
||||
```
|
||||
|
||||
#### 方式二:手动部署
|
||||
```bash
|
||||
# 1. 解压部署包
|
||||
tar -xzf emotion-museum-*.tar.gz
|
||||
cd emotion-museum-*
|
||||
|
||||
# 2. 配置环境变量
|
||||
cp .env .env.local
|
||||
vim .env.local
|
||||
|
||||
# 3. 手动部署
|
||||
chmod +x deploy.sh
|
||||
./deploy.sh
|
||||
```
|
||||
|
||||
### 3. 验证部署
|
||||
```bash
|
||||
# 查看服务状态
|
||||
./manage.sh status
|
||||
|
||||
# 健康检查
|
||||
./manage.sh health
|
||||
|
||||
# 查看日志
|
||||
./manage.sh logs
|
||||
```
|
||||
|
||||
### 4. 访问应用
|
||||
- **前端应用**: http://localhost
|
||||
- **API网关**: http://localhost:9000
|
||||
- **Nacos控制台**: http://localhost:8848/nacos (nacos/nacos)
|
||||
|
||||
## ⚙️ 配置说明
|
||||
|
||||
### 必须配置项
|
||||
编辑 `.env` 文件中的以下配置:
|
||||
|
||||
```bash
|
||||
# Coze API配置(必须)
|
||||
COZE_API_TOKEN=your-actual-coze-api-token
|
||||
|
||||
# 数据库密码(建议修改)
|
||||
MYSQL_ROOT_PASSWORD=your-secure-password
|
||||
MYSQL_PASSWORD=your-secure-password
|
||||
```
|
||||
|
||||
### 可选配置项
|
||||
```bash
|
||||
# 时区设置
|
||||
TZ=Asia/Shanghai
|
||||
|
||||
# 域名配置(生产环境)
|
||||
DOMAIN_NAME=your-domain.com
|
||||
```
|
||||
|
||||
## 🛠️ 管理命令
|
||||
|
||||
```bash
|
||||
# 服务管理
|
||||
./manage.sh start # 启动服务
|
||||
./manage.sh stop # 停止服务
|
||||
./manage.sh restart # 重启服务
|
||||
./manage.sh status # 查看状态
|
||||
|
||||
# 日志管理
|
||||
./manage.sh logs # 查看所有日志
|
||||
./manage.sh logs -f # 跟踪日志
|
||||
./manage.sh logs -s ai # 查看AI服务日志
|
||||
|
||||
# 数据管理
|
||||
./manage.sh backup # 备份数据
|
||||
./manage.sh restore file # 恢复数据
|
||||
|
||||
# 监控
|
||||
./manage.sh monitor # 监控面板
|
||||
./manage.sh health # 健康检查
|
||||
```
|
||||
|
||||
## 🔧 生产环境配置
|
||||
|
||||
### 1. 使用生产配置
|
||||
```bash
|
||||
# 使用生产环境配置
|
||||
docker-compose -f docker-compose.prod.yml up -d
|
||||
```
|
||||
|
||||
### 2. 配置HTTPS
|
||||
```bash
|
||||
# 1. 放置SSL证书
|
||||
cp your-domain.crt deploy/nginx/ssl/emotion-museum.crt
|
||||
cp your-domain.key deploy/nginx/ssl/emotion-museum.key
|
||||
|
||||
# 2. 修改Nginx配置
|
||||
vim deploy/nginx/conf.d/emotion-museum.conf
|
||||
# 取消HTTPS相关配置的注释
|
||||
|
||||
# 3. 重启Nginx
|
||||
docker-compose restart nginx
|
||||
```
|
||||
|
||||
### 3. 配置域名
|
||||
```bash
|
||||
# 修改Nginx配置中的域名
|
||||
vim deploy/nginx/conf.d/emotion-museum.conf
|
||||
# 将 localhost 替换为您的域名
|
||||
```
|
||||
|
||||
## 🚨 故障排除
|
||||
|
||||
### 常见问题
|
||||
|
||||
1. **端口冲突**
|
||||
```bash
|
||||
# 检查端口占用
|
||||
netstat -tlnp | grep :80
|
||||
netstat -tlnp | grep :3306
|
||||
```
|
||||
|
||||
2. **服务启动失败**
|
||||
```bash
|
||||
# 查看具体错误
|
||||
./manage.sh logs -s service-name
|
||||
```
|
||||
|
||||
3. **数据库连接失败**
|
||||
```bash
|
||||
# 检查数据库状态
|
||||
docker-compose exec mysql mysqladmin ping -u root -p
|
||||
```
|
||||
|
||||
4. **前端访问404**
|
||||
```bash
|
||||
# 检查Nginx配置
|
||||
docker-compose exec nginx nginx -t
|
||||
```
|
||||
|
||||
### 获取帮助
|
||||
- 查看详细文档: `cat DEPLOY.md`
|
||||
- 查看版本信息: `cat VERSION.txt`
|
||||
- 查看管理命令: `./manage.sh --help`
|
||||
|
||||
## 📞 技术支持
|
||||
|
||||
如遇到问题,请:
|
||||
1. 查看相关服务日志
|
||||
2. 检查配置文件
|
||||
3. 参考 DEPLOY.md 中的故障排除指南
|
||||
4. 联系技术支持团队
|
||||
|
||||
---
|
||||
**部署完成后,请及时修改默认密码和敏感配置!**
|
||||
@@ -0,0 +1,260 @@
|
||||
# 情绪博物馆 - 测试环境部署指南
|
||||
|
||||
## 项目简介
|
||||
|
||||
情绪博物馆是一个基于Spring Cloud Alibaba微服务架构的情感AI对话平台,集成了Coze AI平台,提供智能情感分析和对话功能。
|
||||
|
||||
## 系统架构
|
||||
|
||||
- **前端**: Vue 3 + Ant Design
|
||||
- **网关**: Spring Cloud Gateway
|
||||
- **微服务**: 用户服务、AI服务
|
||||
- **注册中心**: Nacos
|
||||
- **数据库**: MySQL 8.0
|
||||
- **缓存**: Redis 7
|
||||
- **容器化**: Docker + Docker Compose
|
||||
|
||||
## 快速部署
|
||||
|
||||
### 1. 环境要求
|
||||
|
||||
- **操作系统**: Linux/macOS/Windows (推荐 Ubuntu 20.04+)
|
||||
- **内存**: 最低 4GB,推荐 8GB+
|
||||
- **磁盘**: 最低 20GB 可用空间
|
||||
- **网络**: 能够访问互联网
|
||||
|
||||
### 2. 一键部署
|
||||
|
||||
```bash
|
||||
# 下载部署包并解压
|
||||
cd emotion-museum-1.0.0-20250713_111829
|
||||
|
||||
# 执行一键部署(包含环境安装、数据库初始化、服务部署)
|
||||
chmod +x deploy.sh
|
||||
./deploy.sh
|
||||
```
|
||||
|
||||
### 3. 分步部署
|
||||
|
||||
如果需要分步执行,可以使用以下命令:
|
||||
|
||||
```bash
|
||||
# 1. 安装基础环境 (Java, Maven, Node.js, Docker等)
|
||||
./deploy.sh install-env
|
||||
|
||||
# 2. 初始化数据库
|
||||
./deploy.sh init-db
|
||||
|
||||
# 3. 构建应用镜像
|
||||
./deploy.sh build
|
||||
|
||||
# 4. 启动服务
|
||||
./deploy.sh start
|
||||
```
|
||||
|
||||
### 4. 跳过某些步骤
|
||||
|
||||
```bash
|
||||
# 跳过环境安装(如果已安装)
|
||||
./deploy.sh --skip-env
|
||||
|
||||
# 跳过数据库初始化(如果已初始化)
|
||||
./deploy.sh --skip-db
|
||||
|
||||
# 启用调试模式
|
||||
./deploy.sh --debug
|
||||
```
|
||||
|
||||
## 服务管理
|
||||
|
||||
### 查看服务状态
|
||||
```bash
|
||||
./deploy.sh status
|
||||
```
|
||||
|
||||
### 查看服务日志
|
||||
```bash
|
||||
# 查看所有服务日志
|
||||
./deploy.sh logs
|
||||
|
||||
# 查看特定服务日志
|
||||
./deploy.sh logs gateway
|
||||
./deploy.sh logs user-service
|
||||
./deploy.sh logs ai-service
|
||||
|
||||
# 实时跟踪日志
|
||||
./deploy.sh logs -f
|
||||
```
|
||||
|
||||
### 重启服务
|
||||
```bash
|
||||
# 重启所有服务
|
||||
./deploy.sh restart
|
||||
|
||||
# 重启特定服务
|
||||
./deploy.sh restart gateway
|
||||
```
|
||||
|
||||
### 停止服务
|
||||
```bash
|
||||
./deploy.sh stop
|
||||
```
|
||||
|
||||
### 健康检查
|
||||
```bash
|
||||
./deploy.sh health
|
||||
```
|
||||
|
||||
### 备份数据
|
||||
```bash
|
||||
./deploy.sh backup
|
||||
```
|
||||
|
||||
### 更新服务
|
||||
```bash
|
||||
./deploy.sh update
|
||||
```
|
||||
|
||||
### 清理资源
|
||||
```bash
|
||||
./deploy.sh clean
|
||||
```
|
||||
|
||||
## 访问地址
|
||||
|
||||
部署完成后,可以通过以下地址访问:
|
||||
|
||||
- **前端应用**: http://localhost
|
||||
- **API网关**: http://localhost:9000
|
||||
- **Nacos控制台**: http://localhost:8848/nacos (用户名/密码: nacos/nacos)
|
||||
|
||||
## 配置说明
|
||||
|
||||
### 环境变量配置
|
||||
|
||||
主要配置文件:`.env.test`
|
||||
|
||||
```bash
|
||||
# 服务器IP(重要:部署时请修改为实际IP)
|
||||
SERVER_IP=localhost
|
||||
|
||||
# 数据库配置
|
||||
MYSQL_HOST=localhost
|
||||
MYSQL_PORT=3306
|
||||
MYSQL_USERNAME=emotion
|
||||
MYSQL_PASSWORD=emotion123
|
||||
|
||||
# Redis配置
|
||||
REDIS_HOST=localhost
|
||||
REDIS_PORT=6379
|
||||
|
||||
# Nacos配置
|
||||
NACOS_SERVER_ADDR=localhost:8848
|
||||
|
||||
# COZE AI配置(重要:请配置实际的API Token)
|
||||
COZE_API_TOKEN=your-coze-api-token
|
||||
```
|
||||
|
||||
### 端口配置
|
||||
|
||||
- **前端**: 80 (Nginx)
|
||||
- **网关**: 9000
|
||||
- **用户服务**: 9001
|
||||
- **AI服务**: 9002
|
||||
- **MySQL**: 3306
|
||||
- **Redis**: 6379
|
||||
- **Nacos**: 8848
|
||||
|
||||
## 故障排除
|
||||
|
||||
### 常见问题
|
||||
|
||||
1. **Docker服务未启动**
|
||||
```bash
|
||||
sudo systemctl start docker
|
||||
sudo systemctl enable docker
|
||||
```
|
||||
|
||||
2. **端口被占用**
|
||||
```bash
|
||||
# 查看端口占用
|
||||
netstat -tlnp | grep :端口号
|
||||
|
||||
# 修改 .env.test 文件中的端口配置
|
||||
```
|
||||
|
||||
3. **内存不足**
|
||||
```bash
|
||||
# 调整JVM内存配置
|
||||
export JVM_XMS=256m
|
||||
export JVM_XMX=512m
|
||||
```
|
||||
|
||||
4. **数据库连接失败**
|
||||
```bash
|
||||
# 检查MySQL容器状态
|
||||
docker logs emotion-mysql
|
||||
|
||||
# 重新初始化数据库
|
||||
./deploy.sh init-db
|
||||
```
|
||||
|
||||
### 查看详细日志
|
||||
|
||||
```bash
|
||||
# 查看部署日志
|
||||
./deploy.sh logs --debug
|
||||
|
||||
# 查看容器状态
|
||||
docker ps -a
|
||||
|
||||
# 查看容器日志
|
||||
docker logs emotion-gateway
|
||||
docker logs emotion-mysql
|
||||
docker logs emotion-nacos
|
||||
```
|
||||
|
||||
## 开发调试
|
||||
|
||||
### 本地开发模式
|
||||
|
||||
```bash
|
||||
# 启用调试模式
|
||||
export DEBUG_MODE=true
|
||||
./deploy.sh --debug
|
||||
```
|
||||
|
||||
### 修改配置
|
||||
|
||||
1. 修改后端配置:`backend/config/application-test.yml`
|
||||
2. 修改前端配置:`frontend/config/test.env.js`
|
||||
3. 修改环境变量:`.env.test`
|
||||
|
||||
### 重新构建
|
||||
|
||||
```bash
|
||||
# 重新构建并部署
|
||||
./deploy.sh build
|
||||
./deploy.sh restart
|
||||
```
|
||||
|
||||
## 生产环境部署
|
||||
|
||||
1. 修改 `.env.test` 中的配置
|
||||
2. 配置实际的服务器IP
|
||||
3. 配置HTTPS证书(如需要)
|
||||
4. 配置域名解析(如需要)
|
||||
5. 调整资源限制和性能参数
|
||||
|
||||
## 技术支持
|
||||
|
||||
如遇到问题,请检查:
|
||||
|
||||
1. 系统资源是否充足
|
||||
2. 网络连接是否正常
|
||||
3. 配置文件是否正确
|
||||
4. 日志中的错误信息
|
||||
|
||||
更多详细信息请参考:
|
||||
- `DEPLOY.md` - 详细部署文档
|
||||
- `QUICK_START.md` - 快速开始指南
|
||||
@@ -0,0 +1,29 @@
|
||||
情绪博物馆 - 版本信息
|
||||
========================
|
||||
|
||||
项目名称: emotion-museum
|
||||
版本号: 1.0.0
|
||||
构建时间: 20250713_111829
|
||||
构建环境: Darwin x86_64
|
||||
|
||||
前端信息:
|
||||
- Node.js: v16.20.2
|
||||
- npm: 8.19.4
|
||||
|
||||
后端信息:
|
||||
- Java: java 20 2023-03-21
|
||||
- Maven: Apache Maven 3.9.9 (8e8579a9e76f7d015ee5ec7bfcdc97d260186937)
|
||||
|
||||
Git信息:
|
||||
- 分支: main
|
||||
- 提交: ec81706
|
||||
- 时间: Mon May 26 20:04:17 2025 +0800
|
||||
|
||||
文件清单:
|
||||
- 前端构建产物: frontend/
|
||||
- 后端JAR文件: backend/
|
||||
- 数据库脚本: database/
|
||||
- 部署配置: deploy/
|
||||
- Docker配置: docker-compose*.yml
|
||||
- 部署脚本: *.sh
|
||||
- 说明文档: *.md
|
||||
@@ -0,0 +1,49 @@
|
||||
# AI服务Dockerfile - 测试环境版本
|
||||
FROM openjdk:17-jdk-alpine
|
||||
|
||||
# 构建参数
|
||||
ARG JAR_FILE=emotion-ai-1.0.0.jar
|
||||
ARG CONFIG_FILE=config/ai-test.yml
|
||||
|
||||
# 设置工作目录
|
||||
WORKDIR /app
|
||||
|
||||
# 安装必要的工具
|
||||
RUN apk add --no-cache curl tzdata && \
|
||||
cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
|
||||
echo "Asia/Shanghai" > /etc/timezone
|
||||
|
||||
# 创建运行用户
|
||||
RUN addgroup -g 1000 emotion && \
|
||||
adduser -D -s /bin/sh -u 1000 -G emotion emotion
|
||||
|
||||
# 创建必要的目录
|
||||
RUN mkdir -p /app/config /data/logs/emotion-museum /tmp/emotion-ai && \
|
||||
chown -R emotion:emotion /app /data /tmp/emotion-ai
|
||||
|
||||
# 复制jar文件和配置文件
|
||||
COPY ${JAR_FILE} app.jar
|
||||
COPY ${CONFIG_FILE} config/application.yml
|
||||
|
||||
# 设置文件权限
|
||||
RUN chown -R emotion:emotion /app
|
||||
|
||||
# 切换到非root用户
|
||||
USER emotion
|
||||
|
||||
# 健康检查
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
|
||||
CMD curl -f http://localhost:9002/actuator/health || exit 1
|
||||
|
||||
# 暴露端口
|
||||
EXPOSE 9002
|
||||
|
||||
# 启动命令
|
||||
ENTRYPOINT ["java", "-jar", \
|
||||
"-Xms${JVM_XMS:-512m}", "-Xmx${JVM_XMX:-1024m}", \
|
||||
"-Djava.security.egd=file:/dev/./urandom", \
|
||||
"-Dspring.profiles.active=${SPRING_PROFILES_ACTIVE:-test}", \
|
||||
"-Dspring.config.location=classpath:/application.yml,file:/app/config/application.yml", \
|
||||
"-Dlogging.file.path=/data/logs/emotion-museum", \
|
||||
"-Dfile.temp-dir=/tmp/emotion-ai", \
|
||||
"app.jar"]
|
||||
@@ -0,0 +1,221 @@
|
||||
# AI服务测试环境配置
|
||||
server:
|
||||
port: 9002
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: emotion-ai
|
||||
profiles:
|
||||
active: test
|
||||
cloud:
|
||||
nacos:
|
||||
discovery:
|
||||
server-addr: ${NACOS_SERVER_ADDR:localhost:8848}
|
||||
namespace: emotion-test
|
||||
group: TEST_GROUP
|
||||
enabled: true
|
||||
ip: ${SERVER_IP:localhost}
|
||||
port: ${server.port}
|
||||
metadata:
|
||||
version: 1.0.0
|
||||
environment: test
|
||||
config:
|
||||
server-addr: ${NACOS_SERVER_ADDR:localhost:8848}
|
||||
file-extension: yml
|
||||
namespace: emotion-test
|
||||
group: TEST_GROUP
|
||||
enabled: true
|
||||
datasource:
|
||||
url: jdbc:mysql://${MYSQL_HOST:localhost}:${MYSQL_PORT:3306}/emotion_museum?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
|
||||
username: ${MYSQL_USERNAME:emotion}
|
||||
password: ${MYSQL_PASSWORD:emotion123}
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
hikari:
|
||||
pool-name: EmotionAITestHikariCP
|
||||
minimum-idle: 3
|
||||
maximum-pool-size: 15
|
||||
auto-commit: true
|
||||
idle-timeout: 30000
|
||||
max-lifetime: 1800000
|
||||
connection-timeout: 30000
|
||||
connection-test-query: SELECT 1
|
||||
data:
|
||||
redis:
|
||||
host: ${REDIS_HOST:localhost}
|
||||
port: ${REDIS_PORT:6379}
|
||||
password: ${REDIS_PASSWORD:}
|
||||
database: 2
|
||||
timeout: 6000ms
|
||||
lettuce:
|
||||
pool:
|
||||
max-active: 8
|
||||
max-wait: -1ms
|
||||
max-idle: 8
|
||||
min-idle: 2
|
||||
|
||||
# MyBatis Plus配置
|
||||
mybatis-plus:
|
||||
configuration:
|
||||
map-underscore-to-camel-case: true
|
||||
cache-enabled: true
|
||||
call-setters-on-nulls: true
|
||||
jdbc-type-for-null: 'null'
|
||||
log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl
|
||||
global-config:
|
||||
db-config:
|
||||
id-type: assign_uuid
|
||||
logic-delete-field: is_deleted
|
||||
logic-delete-value: 1
|
||||
logic-not-delete-value: 0
|
||||
banner: false
|
||||
mapper-locations: classpath*:mapper/**/*.xml
|
||||
|
||||
# 日志配置
|
||||
logging:
|
||||
level:
|
||||
root: INFO
|
||||
com.emotionmuseum: INFO
|
||||
com.emotionmuseum.ai.mapper: DEBUG
|
||||
org.springframework.ai: INFO
|
||||
org.springframework.web: INFO
|
||||
pattern:
|
||||
console: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%logger{36}] - %msg%n"
|
||||
file: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%logger{36}] - %msg%n"
|
||||
file:
|
||||
name: /data/logs/emotion-museum/ai-service.log
|
||||
max-size: 100MB
|
||||
max-history: 30
|
||||
|
||||
# 管理端点
|
||||
management:
|
||||
endpoints:
|
||||
web:
|
||||
exposure:
|
||||
include: health,info,metrics,prometheus,env,configprops
|
||||
base-path: /actuator
|
||||
endpoint:
|
||||
health:
|
||||
show-details: always
|
||||
show-components: always
|
||||
metrics:
|
||||
export:
|
||||
prometheus:
|
||||
enabled: true
|
||||
health:
|
||||
redis:
|
||||
enabled: true
|
||||
db:
|
||||
enabled: true
|
||||
|
||||
# COZE AI配置
|
||||
coze:
|
||||
api:
|
||||
token: ${COZE_API_TOKEN:your-coze-api-token}
|
||||
base-url: https://api.coze.cn
|
||||
bot-id: 7523042446285439016
|
||||
workflow-id: 7523047462895796287
|
||||
timeout: 30000
|
||||
retry-count: 3
|
||||
max-tokens: 2000
|
||||
temperature: 0.7
|
||||
endpoints:
|
||||
chat: /v3/chat
|
||||
bot-info: /v1/bot/get_online_info
|
||||
conversation: /v1/conversation/create
|
||||
rate-limit:
|
||||
requests-per-minute: 60
|
||||
requests-per-hour: 1000
|
||||
|
||||
# Spring AI配置
|
||||
spring:
|
||||
ai:
|
||||
retry:
|
||||
max-attempts: 3
|
||||
backoff:
|
||||
initial-interval: 1000
|
||||
multiplier: 2
|
||||
max-interval: 10000
|
||||
timeout: 30s
|
||||
|
||||
# 对话配置
|
||||
conversation:
|
||||
max-history: 20
|
||||
session-timeout: 1800
|
||||
guest-session-timeout: 600
|
||||
max-message-length: 2000
|
||||
auto-save: true
|
||||
cache:
|
||||
enabled: true
|
||||
ttl: 3600
|
||||
|
||||
# 情感分析配置
|
||||
emotion:
|
||||
analysis:
|
||||
enabled: true
|
||||
confidence-threshold: 0.6
|
||||
cache-results: true
|
||||
cache-ttl: 1800
|
||||
categories:
|
||||
- joy
|
||||
- sadness
|
||||
- anger
|
||||
- fear
|
||||
- surprise
|
||||
- disgust
|
||||
- neutral
|
||||
|
||||
# 限流配置
|
||||
rate-limit:
|
||||
enabled: true
|
||||
default-limit: 20
|
||||
default-window: 60
|
||||
api-limits:
|
||||
"/chat": 10
|
||||
"/emotion/analyze": 30
|
||||
"/conversation/create": 5
|
||||
|
||||
# 缓存配置
|
||||
cache:
|
||||
redis:
|
||||
default-ttl: 3600
|
||||
conversation-ttl: 1800
|
||||
emotion-analysis-ttl: 7200
|
||||
user-session-ttl: 3600
|
||||
|
||||
# 安全配置
|
||||
security:
|
||||
ignore-urls:
|
||||
- /actuator/**
|
||||
- /api/public/**
|
||||
- /swagger-ui/**
|
||||
- /v3/api-docs/**
|
||||
|
||||
# 文件配置
|
||||
file:
|
||||
temp-dir: /tmp/emotion-ai
|
||||
max-size: 5MB
|
||||
cleanup-interval: 3600
|
||||
|
||||
# 监控告警配置
|
||||
alert:
|
||||
enabled: true
|
||||
thresholds:
|
||||
api-response-time: 5000
|
||||
error-rate: 10
|
||||
coze-api-failure-rate: 20
|
||||
notification:
|
||||
enabled: false
|
||||
|
||||
# 测试环境特殊配置
|
||||
test:
|
||||
debug:
|
||||
enabled: true
|
||||
log-requests: true
|
||||
log-responses: false
|
||||
log-ai-interactions: true
|
||||
mock:
|
||||
enabled: false
|
||||
coze-api: false
|
||||
data:
|
||||
auto-init: true
|
||||
sample-conversations: true
|
||||
@@ -0,0 +1,80 @@
|
||||
# 用户服务 Docker环境配置
|
||||
server:
|
||||
port: 9001
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: emotion-user
|
||||
profiles:
|
||||
active: docker
|
||||
cloud:
|
||||
nacos:
|
||||
discovery:
|
||||
server-addr: ${NACOS_SERVER_ADDR:nacos:8848}
|
||||
namespace: public
|
||||
group: DEFAULT_GROUP
|
||||
config:
|
||||
server-addr: ${NACOS_SERVER_ADDR:nacos:8848}
|
||||
file-extension: yml
|
||||
namespace: public
|
||||
group: DEFAULT_GROUP
|
||||
datasource:
|
||||
url: jdbc:mysql://${MYSQL_HOST:mysql}:${MYSQL_PORT:3306}/emotion_museum?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
|
||||
username: root
|
||||
password: 123456
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
hikari:
|
||||
pool-name: EmotionUserHikariCP
|
||||
minimum-idle: 5
|
||||
maximum-pool-size: 20
|
||||
auto-commit: true
|
||||
idle-timeout: 30000
|
||||
max-lifetime: 1800000
|
||||
connection-timeout: 30000
|
||||
data:
|
||||
redis:
|
||||
host: ${REDIS_HOST:redis}
|
||||
port: ${REDIS_PORT:6379}
|
||||
password:
|
||||
database: 2
|
||||
timeout: 6000ms
|
||||
lettuce:
|
||||
pool:
|
||||
max-active: 8
|
||||
max-wait: -1ms
|
||||
max-idle: 8
|
||||
min-idle: 0
|
||||
|
||||
# MyBatis Plus配置
|
||||
mybatis-plus:
|
||||
configuration:
|
||||
map-underscore-to-camel-case: true
|
||||
cache-enabled: false
|
||||
call-setters-on-nulls: true
|
||||
jdbc-type-for-null: 'null'
|
||||
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
||||
global-config:
|
||||
db-config:
|
||||
id-type: assign_uuid
|
||||
logic-delete-field: isDeleted
|
||||
logic-delete-value: 1
|
||||
logic-not-delete-value: 0
|
||||
banner: false
|
||||
|
||||
# 日志配置
|
||||
logging:
|
||||
level:
|
||||
com.emotionmuseum: DEBUG
|
||||
com.emotionmuseum.user.mapper: DEBUG
|
||||
pattern:
|
||||
console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level [%logger{50}] - %msg%n"
|
||||
|
||||
# 管理端点
|
||||
management:
|
||||
endpoints:
|
||||
web:
|
||||
exposure:
|
||||
include: health,info,metrics,prometheus
|
||||
endpoint:
|
||||
health:
|
||||
show-details: always
|
||||
@@ -0,0 +1,205 @@
|
||||
# 情绪博物馆测试环境配置
|
||||
# 适用于测试环境部署,使用IP访问,不使用域名
|
||||
|
||||
server:
|
||||
port: 9001
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: emotion-user
|
||||
profiles:
|
||||
active: test
|
||||
cloud:
|
||||
nacos:
|
||||
discovery:
|
||||
server-addr: ${NACOS_SERVER_ADDR:localhost:8848}
|
||||
namespace: emotion-test
|
||||
group: TEST_GROUP
|
||||
enabled: true
|
||||
ip: ${SERVER_IP:localhost}
|
||||
port: ${server.port}
|
||||
metadata:
|
||||
version: 1.0.0
|
||||
environment: test
|
||||
config:
|
||||
server-addr: ${NACOS_SERVER_ADDR:localhost:8848}
|
||||
file-extension: yml
|
||||
namespace: emotion-test
|
||||
group: TEST_GROUP
|
||||
enabled: true
|
||||
refresh-enabled: true
|
||||
datasource:
|
||||
url: jdbc:mysql://${MYSQL_HOST:localhost}:${MYSQL_PORT:3306}/emotion_museum?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
|
||||
username: ${MYSQL_USERNAME:emotion}
|
||||
password: ${MYSQL_PASSWORD:emotion123}
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
hikari:
|
||||
pool-name: EmotionUserTestHikariCP
|
||||
minimum-idle: 3
|
||||
maximum-pool-size: 15
|
||||
auto-commit: true
|
||||
idle-timeout: 30000
|
||||
max-lifetime: 1800000
|
||||
connection-timeout: 30000
|
||||
connection-test-query: SELECT 1
|
||||
data:
|
||||
redis:
|
||||
host: ${REDIS_HOST:localhost}
|
||||
port: ${REDIS_PORT:6379}
|
||||
password: ${REDIS_PASSWORD:}
|
||||
database: 1
|
||||
timeout: 6000ms
|
||||
lettuce:
|
||||
pool:
|
||||
max-active: 8
|
||||
max-wait: -1ms
|
||||
max-idle: 8
|
||||
min-idle: 2
|
||||
|
||||
# MyBatis Plus配置
|
||||
mybatis-plus:
|
||||
configuration:
|
||||
map-underscore-to-camel-case: true
|
||||
cache-enabled: true
|
||||
call-setters-on-nulls: true
|
||||
jdbc-type-for-null: 'null'
|
||||
log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl
|
||||
global-config:
|
||||
db-config:
|
||||
id-type: assign_uuid
|
||||
logic-delete-field: is_deleted
|
||||
logic-delete-value: 1
|
||||
logic-not-delete-value: 0
|
||||
banner: false
|
||||
mapper-locations: classpath*:mapper/**/*.xml
|
||||
|
||||
# 日志配置
|
||||
logging:
|
||||
level:
|
||||
root: INFO
|
||||
com.emotionmuseum: INFO
|
||||
com.emotionmuseum.user.mapper: DEBUG
|
||||
org.springframework.cloud.gateway: INFO
|
||||
org.springframework.web: INFO
|
||||
pattern:
|
||||
console: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%logger{36}] - %msg%n"
|
||||
file: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%logger{36}] - %msg%n"
|
||||
file:
|
||||
name: /data/logs/emotion-museum/user-service.log
|
||||
max-size: 100MB
|
||||
max-history: 30
|
||||
|
||||
# 管理端点
|
||||
management:
|
||||
endpoints:
|
||||
web:
|
||||
exposure:
|
||||
include: health,info,metrics,prometheus,env,configprops
|
||||
base-path: /actuator
|
||||
endpoint:
|
||||
health:
|
||||
show-details: always
|
||||
show-components: always
|
||||
metrics:
|
||||
export:
|
||||
prometheus:
|
||||
enabled: true
|
||||
health:
|
||||
redis:
|
||||
enabled: true
|
||||
db:
|
||||
enabled: true
|
||||
|
||||
# JWT配置
|
||||
jwt:
|
||||
secret: ${JWT_SECRET:emotion-museum-test-secret-key-2025}
|
||||
expiration: ${JWT_EXPIRATION:7200}
|
||||
refresh-expiration: ${JWT_REFRESH_EXPIRATION:86400}
|
||||
|
||||
# COZE AI配置
|
||||
coze:
|
||||
api:
|
||||
token: ${COZE_API_TOKEN:your-coze-api-token}
|
||||
base-url: https://api.coze.cn
|
||||
bot-id: 7523042446285439016
|
||||
workflow-id: 7523047462895796287
|
||||
timeout: 30000
|
||||
retry-count: 3
|
||||
|
||||
# 跨域配置
|
||||
cors:
|
||||
allowed-origins:
|
||||
- "http://localhost:3000"
|
||||
- "http://localhost:8080"
|
||||
- "http://${SERVER_IP:localhost}"
|
||||
- "http://${SERVER_IP:localhost}:3000"
|
||||
- "http://${SERVER_IP:localhost}:8080"
|
||||
allowed-methods:
|
||||
- GET
|
||||
- POST
|
||||
- PUT
|
||||
- DELETE
|
||||
- OPTIONS
|
||||
allowed-headers:
|
||||
- "*"
|
||||
allow-credentials: true
|
||||
max-age: 3600
|
||||
|
||||
# 文件上传配置
|
||||
file:
|
||||
upload:
|
||||
path: /data/uploads/emotion-museum
|
||||
max-size: 10MB
|
||||
allowed-types:
|
||||
- image/jpeg
|
||||
- image/png
|
||||
- image/gif
|
||||
- image/webp
|
||||
|
||||
# 缓存配置
|
||||
cache:
|
||||
redis:
|
||||
default-ttl: 3600
|
||||
user-info-ttl: 1800
|
||||
conversation-ttl: 7200
|
||||
|
||||
# 限流配置
|
||||
rate-limit:
|
||||
enabled: true
|
||||
default-limit: 100
|
||||
default-window: 60
|
||||
api-limits:
|
||||
"/api/auth/login": 10
|
||||
"/api/auth/register": 5
|
||||
"/api/ai/chat": 20
|
||||
|
||||
# 安全配置
|
||||
security:
|
||||
ignore-urls:
|
||||
- /actuator/**
|
||||
- /api/auth/login
|
||||
- /api/auth/register
|
||||
- /api/public/**
|
||||
- /swagger-ui/**
|
||||
- /v3/api-docs/**
|
||||
|
||||
# 监控告警配置
|
||||
alert:
|
||||
enabled: true
|
||||
thresholds:
|
||||
cpu-usage: 80
|
||||
memory-usage: 85
|
||||
disk-usage: 90
|
||||
response-time: 2000
|
||||
|
||||
# 测试环境特殊配置
|
||||
test:
|
||||
debug:
|
||||
enabled: true
|
||||
log-requests: true
|
||||
log-responses: false
|
||||
mock:
|
||||
enabled: false
|
||||
data:
|
||||
auto-init: true
|
||||
sample-data: true
|
||||
@@ -0,0 +1,79 @@
|
||||
server:
|
||||
port: 9001
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: emotion-user
|
||||
profiles:
|
||||
active: dev
|
||||
datasource:
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
url: jdbc:mysql://localhost:3306/emotion_museum?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true
|
||||
username: root
|
||||
password: 123456
|
||||
hikari:
|
||||
minimum-idle: 5
|
||||
maximum-pool-size: 20
|
||||
idle-timeout: 600000
|
||||
max-lifetime: 1800000
|
||||
connection-timeout: 30000
|
||||
data:
|
||||
redis:
|
||||
host: localhost
|
||||
port: 6379
|
||||
database: 0
|
||||
timeout: 3000ms
|
||||
lettuce:
|
||||
pool:
|
||||
max-active: 20
|
||||
max-idle: 10
|
||||
min-idle: 5
|
||||
max-wait: 3000ms
|
||||
cloud:
|
||||
nacos:
|
||||
discovery:
|
||||
server-addr: localhost:8848
|
||||
namespace: emotion-dev
|
||||
group: DEFAULT_GROUP
|
||||
enabled: false
|
||||
config:
|
||||
enabled: false
|
||||
|
||||
mybatis-plus:
|
||||
configuration:
|
||||
map-underscore-to-camel-case: true
|
||||
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
||||
global-config:
|
||||
db-config:
|
||||
id-type: assign_uuid
|
||||
logic-delete-field: deleted
|
||||
logic-delete-value: 1
|
||||
logic-not-delete-value: 0
|
||||
|
||||
# 监控配置
|
||||
management:
|
||||
endpoints:
|
||||
web:
|
||||
exposure:
|
||||
include: health,info,metrics,prometheus
|
||||
endpoint:
|
||||
health:
|
||||
show-details: always
|
||||
metrics:
|
||||
export:
|
||||
prometheus:
|
||||
enabled: true
|
||||
|
||||
# 日志配置
|
||||
logging:
|
||||
level:
|
||||
com.emotionmuseum: debug
|
||||
com.baomidou.mybatisplus: debug
|
||||
pattern:
|
||||
console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level [%logger{50}] - %msg%n"
|
||||
|
||||
# JWT配置
|
||||
jwt:
|
||||
secret: emotion-museum-secret-key-2025
|
||||
expiration: 86400
|
||||
refresh-expiration: 604800
|
||||
@@ -0,0 +1,215 @@
|
||||
# 网关服务测试环境配置
|
||||
server:
|
||||
port: 9000
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: emotion-gateway
|
||||
profiles:
|
||||
active: test
|
||||
cloud:
|
||||
nacos:
|
||||
discovery:
|
||||
server-addr: ${NACOS_SERVER_ADDR:localhost:8848}
|
||||
namespace: emotion-test
|
||||
group: TEST_GROUP
|
||||
enabled: true
|
||||
ip: ${SERVER_IP:localhost}
|
||||
port: ${server.port}
|
||||
metadata:
|
||||
version: 1.0.0
|
||||
environment: test
|
||||
config:
|
||||
server-addr: ${NACOS_SERVER_ADDR:localhost:8848}
|
||||
file-extension: yml
|
||||
namespace: emotion-test
|
||||
group: TEST_GROUP
|
||||
enabled: true
|
||||
gateway:
|
||||
discovery:
|
||||
locator:
|
||||
enabled: true
|
||||
lower-case-service-id: true
|
||||
routes:
|
||||
# 用户服务路由
|
||||
- id: emotion-user
|
||||
uri: lb://emotion-user
|
||||
predicates:
|
||||
- Path=/api/user/**
|
||||
filters:
|
||||
- StripPrefix=2
|
||||
- name: RequestRateLimiter
|
||||
args:
|
||||
redis-rate-limiter.replenishRate: 10
|
||||
redis-rate-limiter.burstCapacity: 20
|
||||
key-resolver: "#{@ipKeyResolver}"
|
||||
|
||||
# AI服务路由
|
||||
- id: emotion-ai
|
||||
uri: lb://emotion-ai
|
||||
predicates:
|
||||
- Path=/api/ai/**
|
||||
filters:
|
||||
- StripPrefix=2
|
||||
- name: RequestRateLimiter
|
||||
args:
|
||||
redis-rate-limiter.replenishRate: 5
|
||||
redis-rate-limiter.burstCapacity: 10
|
||||
key-resolver: "#{@ipKeyResolver}"
|
||||
|
||||
# 认证服务路由
|
||||
- id: emotion-auth
|
||||
uri: lb://emotion-user
|
||||
predicates:
|
||||
- Path=/api/auth/**
|
||||
filters:
|
||||
- StripPrefix=2
|
||||
|
||||
# 公共API路由
|
||||
- id: emotion-public
|
||||
uri: lb://emotion-user
|
||||
predicates:
|
||||
- Path=/api/public/**
|
||||
filters:
|
||||
- StripPrefix=2
|
||||
|
||||
# 健康检查路由
|
||||
- id: health-check
|
||||
uri: lb://emotion-gateway
|
||||
predicates:
|
||||
- Path=/health
|
||||
filters:
|
||||
- SetPath=/actuator/health
|
||||
|
||||
# 全局过滤器配置
|
||||
default-filters:
|
||||
- name: GlobalRequestLog
|
||||
- name: GlobalResponseLog
|
||||
- name: AddResponseHeader
|
||||
args:
|
||||
name: X-Response-Server
|
||||
value: emotion-gateway-test
|
||||
|
||||
data:
|
||||
redis:
|
||||
host: ${REDIS_HOST:localhost}
|
||||
port: ${REDIS_PORT:6379}
|
||||
password: ${REDIS_PASSWORD:}
|
||||
database: 0
|
||||
timeout: 6000ms
|
||||
lettuce:
|
||||
pool:
|
||||
max-active: 8
|
||||
max-wait: -1ms
|
||||
max-idle: 8
|
||||
min-idle: 2
|
||||
|
||||
# 日志配置
|
||||
logging:
|
||||
level:
|
||||
root: INFO
|
||||
com.emotionmuseum: INFO
|
||||
org.springframework.cloud.gateway: INFO
|
||||
org.springframework.web.reactive: INFO
|
||||
reactor.netty: INFO
|
||||
pattern:
|
||||
console: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%logger{36}] - %msg%n"
|
||||
file: "%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%logger{36}] - %msg%n"
|
||||
file:
|
||||
name: /data/logs/emotion-museum/gateway-service.log
|
||||
max-size: 100MB
|
||||
max-history: 30
|
||||
|
||||
# 管理端点
|
||||
management:
|
||||
endpoints:
|
||||
web:
|
||||
exposure:
|
||||
include: health,info,metrics,prometheus,gateway,env
|
||||
base-path: /actuator
|
||||
endpoint:
|
||||
health:
|
||||
show-details: always
|
||||
show-components: always
|
||||
gateway:
|
||||
enabled: true
|
||||
metrics:
|
||||
export:
|
||||
prometheus:
|
||||
enabled: true
|
||||
|
||||
# 跨域配置
|
||||
cors:
|
||||
configurations:
|
||||
'[/**]':
|
||||
allowed-origins:
|
||||
- "http://localhost:3000"
|
||||
- "http://localhost:8080"
|
||||
- "http://${SERVER_IP:localhost}"
|
||||
- "http://${SERVER_IP:localhost}:3000"
|
||||
- "http://${SERVER_IP:localhost}:8080"
|
||||
allowed-methods:
|
||||
- GET
|
||||
- POST
|
||||
- PUT
|
||||
- DELETE
|
||||
- OPTIONS
|
||||
allowed-headers:
|
||||
- "*"
|
||||
allow-credentials: true
|
||||
max-age: 3600
|
||||
|
||||
# 限流配置
|
||||
rate-limit:
|
||||
enabled: true
|
||||
default-replenish-rate: 10
|
||||
default-burst-capacity: 20
|
||||
routes:
|
||||
emotion-user:
|
||||
replenish-rate: 20
|
||||
burst-capacity: 40
|
||||
emotion-ai:
|
||||
replenish-rate: 5
|
||||
burst-capacity: 10
|
||||
|
||||
# 熔断配置
|
||||
resilience4j:
|
||||
circuitbreaker:
|
||||
instances:
|
||||
emotion-user:
|
||||
failure-rate-threshold: 50
|
||||
wait-duration-in-open-state: 30s
|
||||
sliding-window-size: 10
|
||||
minimum-number-of-calls: 5
|
||||
emotion-ai:
|
||||
failure-rate-threshold: 60
|
||||
wait-duration-in-open-state: 60s
|
||||
sliding-window-size: 10
|
||||
minimum-number-of-calls: 3
|
||||
timelimiter:
|
||||
instances:
|
||||
emotion-user:
|
||||
timeout-duration: 10s
|
||||
emotion-ai:
|
||||
timeout-duration: 30s
|
||||
|
||||
# 安全配置
|
||||
security:
|
||||
ignore-urls:
|
||||
- /actuator/**
|
||||
- /api/auth/login
|
||||
- /api/auth/register
|
||||
- /api/public/**
|
||||
- /health
|
||||
jwt:
|
||||
secret: ${JWT_SECRET:emotion-museum-test-secret-key-2025}
|
||||
expiration: ${JWT_EXPIRATION:7200}
|
||||
|
||||
# 测试环境特殊配置
|
||||
test:
|
||||
debug:
|
||||
enabled: true
|
||||
log-requests: true
|
||||
log-responses: false
|
||||
mock:
|
||||
enabled: false
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,48 @@
|
||||
# 网关服务Dockerfile - 测试环境版本
|
||||
FROM openjdk:17-jdk-alpine
|
||||
|
||||
# 构建参数
|
||||
ARG JAR_FILE=emotion-gateway-1.0.0.jar
|
||||
ARG CONFIG_FILE=config/gateway-test.yml
|
||||
|
||||
# 设置工作目录
|
||||
WORKDIR /app
|
||||
|
||||
# 安装必要的工具
|
||||
RUN apk add --no-cache curl tzdata && \
|
||||
cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
|
||||
echo "Asia/Shanghai" > /etc/timezone
|
||||
|
||||
# 创建运行用户
|
||||
RUN addgroup -g 1000 emotion && \
|
||||
adduser -D -s /bin/sh -u 1000 -G emotion emotion
|
||||
|
||||
# 创建必要的目录
|
||||
RUN mkdir -p /app/config /data/logs/emotion-museum && \
|
||||
chown -R emotion:emotion /app /data
|
||||
|
||||
# 复制jar文件和配置文件
|
||||
COPY ${JAR_FILE} app.jar
|
||||
COPY ${CONFIG_FILE} config/application.yml
|
||||
|
||||
# 设置文件权限
|
||||
RUN chown -R emotion:emotion /app
|
||||
|
||||
# 切换到非root用户
|
||||
USER emotion
|
||||
|
||||
# 健康检查
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
|
||||
CMD curl -f http://localhost:9000/actuator/health || exit 1
|
||||
|
||||
# 暴露端口
|
||||
EXPOSE 9000
|
||||
|
||||
# 启动命令
|
||||
ENTRYPOINT ["java", "-jar", \
|
||||
"-Xms${JVM_XMS:-512m}", "-Xmx${JVM_XMX:-1024m}", \
|
||||
"-Djava.security.egd=file:/dev/./urandom", \
|
||||
"-Dspring.profiles.active=${SPRING_PROFILES_ACTIVE:-test}", \
|
||||
"-Dspring.config.location=classpath:/application.yml,file:/app/config/application.yml", \
|
||||
"-Dlogging.file.path=/data/logs/emotion-museum", \
|
||||
"app.jar"]
|
||||
@@ -0,0 +1,49 @@
|
||||
# 用户服务Dockerfile - 测试环境版本
|
||||
FROM openjdk:17-jdk-alpine
|
||||
|
||||
# 构建参数
|
||||
ARG JAR_FILE=emotion-user-1.0.0.jar
|
||||
ARG CONFIG_FILE=config/application-test.yml
|
||||
|
||||
# 设置工作目录
|
||||
WORKDIR /app
|
||||
|
||||
# 安装必要的工具
|
||||
RUN apk add --no-cache curl tzdata && \
|
||||
cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
|
||||
echo "Asia/Shanghai" > /etc/timezone
|
||||
|
||||
# 创建运行用户
|
||||
RUN addgroup -g 1000 emotion && \
|
||||
adduser -D -s /bin/sh -u 1000 -G emotion emotion
|
||||
|
||||
# 创建必要的目录
|
||||
RUN mkdir -p /app/config /data/logs/emotion-museum /data/uploads/emotion-museum && \
|
||||
chown -R emotion:emotion /app /data
|
||||
|
||||
# 复制jar文件和配置文件
|
||||
COPY ${JAR_FILE} app.jar
|
||||
COPY ${CONFIG_FILE} config/application.yml
|
||||
|
||||
# 设置文件权限
|
||||
RUN chown -R emotion:emotion /app
|
||||
|
||||
# 切换到非root用户
|
||||
USER emotion
|
||||
|
||||
# 健康检查
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
|
||||
CMD curl -f http://localhost:9001/actuator/health || exit 1
|
||||
|
||||
# 暴露端口
|
||||
EXPOSE 9001
|
||||
|
||||
# 启动命令
|
||||
ENTRYPOINT ["java", "-jar", \
|
||||
"-Xms${JVM_XMS:-512m}", "-Xmx${JVM_XMX:-1024m}", \
|
||||
"-Djava.security.egd=file:/dev/./urandom", \
|
||||
"-Dspring.profiles.active=${SPRING_PROFILES_ACTIVE:-test}", \
|
||||
"-Dspring.config.location=classpath:/application.yml,file:/app/config/application.yml", \
|
||||
"-Dlogging.file.path=/data/logs/emotion-museum", \
|
||||
"-Dfile.upload.path=/data/uploads/emotion-museum", \
|
||||
"app.jar"]
|
||||
+819
@@ -0,0 +1,819 @@
|
||||
-- ============================================================================
|
||||
-- 情绪博物馆数据库完整部署脚本
|
||||
-- 版本: v3.0 Final (雪花算法主键版本) - 开发版本
|
||||
-- 创建时间: 2025-07-13
|
||||
-- 数据库类型: MySQL 8.0+
|
||||
-- 说明: 包含完整表结构、索引、初始数据的一体化部署脚本
|
||||
-- 主键类型: VARCHAR(36) 使用雪花算法生成,避免前端精度丢失问题
|
||||
-- 关联策略: 不使用外键约束,通过代码中的ID字段关联
|
||||
-- 特性: 开发阶段 - 先删除表再重新创建,确保表结构是最新的
|
||||
-- 警告: 此脚本会删除现有表和数据,仅适用于开发环境!
|
||||
-- ============================================================================
|
||||
-- 设置SQL模式和字符集
|
||||
SET
|
||||
SQL_MODE = 'NO_AUTO_VALUE_ON_ZERO';
|
||||
|
||||
SET
|
||||
AUTOCOMMIT = 0;
|
||||
|
||||
START TRANSACTION;
|
||||
|
||||
SET
|
||||
time_zone = "+00:00";
|
||||
|
||||
-- 创建数据库
|
||||
CREATE DATABASE IF NOT EXISTS emotion_museum DEFAULT CHARACTER
|
||||
SET
|
||||
utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
USE emotion_museum;
|
||||
|
||||
-- ============================================================================
|
||||
-- 数据库设计原则
|
||||
-- ============================================================================
|
||||
-- 1. 主键策略: 使用VARCHAR(36)雪花算法ID,避免前端精度丢失
|
||||
-- 2. 关联策略: 不使用外键约束,通过代码中的ID字段维护关联关系
|
||||
-- 3. 公共字段: 所有表继承BaseEntity的公共字段
|
||||
-- 4. 索引优化: 为查询频繁的字段创建合适的索引
|
||||
-- 5. 字符集: 统一使用utf8mb4支持emoji和特殊字符
|
||||
-- ============================================================================
|
||||
-- 删除现有表(开发阶段确保表结构最新)
|
||||
-- 警告: 这会删除所有数据!
|
||||
-- ============================================================================
|
||||
DROP TABLE IF EXISTS user_stats;
|
||||
|
||||
DROP TABLE IF EXISTS guest_user;
|
||||
|
||||
DROP TABLE IF EXISTS reward;
|
||||
|
||||
DROP TABLE IF EXISTS achievement;
|
||||
|
||||
DROP TABLE IF EXISTS comment;
|
||||
|
||||
DROP TABLE IF EXISTS community_post;
|
||||
|
||||
DROP TABLE IF EXISTS location_pin;
|
||||
|
||||
DROP TABLE IF EXISTS topic_interaction;
|
||||
|
||||
DROP TABLE IF EXISTS growth_topic;
|
||||
|
||||
DROP TABLE IF EXISTS emotion_record;
|
||||
|
||||
DROP TABLE IF EXISTS emotion_analysis;
|
||||
|
||||
DROP TABLE IF EXISTS coze_api_call;
|
||||
|
||||
DROP TABLE IF EXISTS message;
|
||||
|
||||
DROP TABLE IF EXISTS conversation;
|
||||
|
||||
DROP TABLE IF EXISTS user;
|
||||
|
||||
-- ============================================================================
|
||||
-- 1. 用户表 (user)
|
||||
-- ============================================================================
|
||||
CREATE TABLE user (
|
||||
id VARCHAR(36) PRIMARY KEY, -- UUID主键
|
||||
account VARCHAR(50) NOT NULL UNIQUE, -- 账号
|
||||
password VARCHAR(255) NOT NULL, -- 密码(加密后)
|
||||
username VARCHAR(50) NOT NULL UNIQUE, -- 用户名
|
||||
email VARCHAR(100) NOT NULL UNIQUE, -- 邮箱
|
||||
phone VARCHAR(20) UNIQUE, -- 手机号
|
||||
avatar VARCHAR(500), -- 头像URL
|
||||
nickname VARCHAR(50) NOT NULL, -- 昵称
|
||||
birth_date DATE, -- 生日
|
||||
location VARCHAR(100), -- 所在地
|
||||
bio TEXT, -- 个人简介
|
||||
member_level VARCHAR(20) NOT NULL DEFAULT 'free', -- 会员等级
|
||||
total_days INT NOT NULL DEFAULT 0, -- 使用天数
|
||||
-- 成长数据
|
||||
self_awareness DECIMAL(5, 2) NOT NULL DEFAULT 50.00, -- 自我感知
|
||||
emotional_resilience DECIMAL(5, 2) NOT NULL DEFAULT 50.00, -- 情绪韧性
|
||||
action_power DECIMAL(5, 2) NOT NULL DEFAULT 50.00, -- 行动力
|
||||
empathy DECIMAL(5, 2) NOT NULL DEFAULT 50.00, -- 共情力
|
||||
life_enthusiasm DECIMAL(5, 2) NOT NULL DEFAULT 50.00, -- 生活热度
|
||||
-- 状态字段
|
||||
status TINYINT NOT NULL DEFAULT 1, -- 状态: 0-禁用, 1-正常
|
||||
is_verified TINYINT NOT NULL DEFAULT 0, -- 是否已验证: 0-未验证, 1-已验证
|
||||
last_active_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 最后活跃时间
|
||||
-- 公共字段
|
||||
create_by VARCHAR(36), -- 创建人ID
|
||||
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 创建时间
|
||||
update_by VARCHAR(36), -- 更新人ID
|
||||
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
|
||||
is_deleted TINYINT NOT NULL DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
|
||||
remarks VARCHAR(500) -- 备注
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户表';
|
||||
|
||||
-- ============================================================================
|
||||
-- 2. 对话表 (conversation)
|
||||
-- 关联说明: user_id 关联 user.id,通过代码逻辑维护关联关系
|
||||
-- ============================================================================
|
||||
CREATE TABLE conversation (
|
||||
id VARCHAR(36) PRIMARY KEY, -- UUID主键
|
||||
user_id VARCHAR(36) NOT NULL, -- 用户ID (关联user.id)
|
||||
user_type VARCHAR(20) NOT NULL DEFAULT 'registered', -- 用户类型: registered-注册用户, guest-访客用户
|
||||
title VARCHAR(200), -- 对话标题
|
||||
type VARCHAR(50) NOT NULL DEFAULT 'emotion_chat', -- 对话类型
|
||||
status VARCHAR(20) NOT NULL DEFAULT 'active', -- 状态: active-活跃, ended-结束, archived-归档
|
||||
coze_conversation_id VARCHAR(100), -- Coze对话ID
|
||||
bot_id VARCHAR(50), -- 使用的Bot ID
|
||||
workflow_id VARCHAR(50), -- 使用的Workflow ID
|
||||
initial_message TEXT, -- 初始消息
|
||||
context TEXT, -- 上下文信息
|
||||
primary_emotion VARCHAR(50), -- 主要情绪
|
||||
emotion_intensity DECIMAL(3, 2), -- 情绪强度
|
||||
emotion_trend VARCHAR(50), -- 情绪趋势
|
||||
keywords JSON, -- 关键词
|
||||
ai_insights TEXT, -- AI洞察
|
||||
confidence DECIMAL(3, 2), -- 分析置信度
|
||||
start_time DATETIME, -- 开始时间
|
||||
end_time DATETIME, -- 结束时间
|
||||
last_active_time DATETIME DEFAULT CURRENT_TIMESTAMP, -- 最后活跃时间
|
||||
message_count INT NOT NULL DEFAULT 0, -- 消息数量
|
||||
total_tokens INT DEFAULT 0, -- 总Token使用量
|
||||
total_cost DECIMAL(10, 4) DEFAULT 0.0000, -- 总费用
|
||||
client_ip VARCHAR(45), -- 客户端IP地址 (支持IPv6)
|
||||
user_agent TEXT, -- 用户代理信息
|
||||
summary TEXT, -- 对话摘要
|
||||
tags JSON, -- 标签
|
||||
metadata JSON, -- 扩展元数据
|
||||
-- 公共字段
|
||||
create_by VARCHAR(36), -- 创建人ID
|
||||
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 创建时间
|
||||
update_by VARCHAR(36), -- 更新人ID
|
||||
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
|
||||
is_deleted TINYINT NOT NULL DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
|
||||
remarks VARCHAR(500) -- 备注
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '对话表';
|
||||
|
||||
-- ============================================================================
|
||||
-- 3. 消息表 (message)
|
||||
-- 关联说明: conversation_id 关联 conversation.id,通过代码逻辑维护关联关系
|
||||
-- ============================================================================
|
||||
CREATE TABLE message (
|
||||
id VARCHAR(36) PRIMARY KEY, -- UUID主键
|
||||
conversation_id VARCHAR(36) NOT NULL, -- 对话ID (关联conversation.id)
|
||||
content TEXT NOT NULL, -- 消息内容
|
||||
type VARCHAR(50) NOT NULL DEFAULT 'text', -- 消息类型
|
||||
sender VARCHAR(20) NOT NULL, -- 发送者: user-用户, assistant-AI助手
|
||||
timestamp DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 消息时间戳
|
||||
coze_chat_id VARCHAR(50), -- Coze平台的聊天ID
|
||||
coze_message_id VARCHAR(50), -- Coze平台的消息ID
|
||||
status VARCHAR(20) DEFAULT 'sent', -- 消息状态: sending/sent/failed/processing
|
||||
error_message TEXT, -- 错误信息
|
||||
emotion_score DECIMAL(3, 2), -- 情绪评分
|
||||
emotion_type VARCHAR(50), -- 情绪类型
|
||||
emotion_confidence DECIMAL(3, 2), -- 情绪分析置信度
|
||||
prompt_tokens INT DEFAULT 0, -- 输入Token数
|
||||
completion_tokens INT DEFAULT 0, -- 输出Token数
|
||||
total_tokens INT DEFAULT 0, -- 总Token数
|
||||
api_cost DECIMAL(10, 6) DEFAULT 0.000000, -- API调用费用
|
||||
is_read TINYINT NOT NULL DEFAULT 0, -- 是否已读: 0-未读, 1-已读
|
||||
parent_message_id VARCHAR(36), -- 父消息ID(用于回复链)
|
||||
emotion_analysis JSON, -- 情绪分析结果
|
||||
metadata JSON, -- 扩展元数据
|
||||
-- 公共字段
|
||||
create_by VARCHAR(36), -- 创建人ID
|
||||
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 创建时间
|
||||
update_by VARCHAR(36), -- 更新人ID
|
||||
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
|
||||
is_deleted TINYINT NOT NULL DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
|
||||
remarks VARCHAR(500) -- 备注
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '消息表';
|
||||
|
||||
-- ============================================================================
|
||||
-- 4. Coze API调用记录表 (coze_api_call)
|
||||
-- ============================================================================
|
||||
CREATE TABLE coze_api_call (
|
||||
id VARCHAR(36) PRIMARY KEY, -- UUID主键
|
||||
conversation_id VARCHAR(36), -- 对话ID
|
||||
message_id VARCHAR(36), -- 消息ID
|
||||
-- Coze API 信息
|
||||
coze_chat_id VARCHAR(50), -- Coze聊天ID
|
||||
coze_conversation_id VARCHAR(50), -- Coze对话ID
|
||||
bot_id VARCHAR(50) NOT NULL, -- Bot ID
|
||||
workflow_id VARCHAR(50), -- Workflow ID
|
||||
user_id VARCHAR(36) NOT NULL, -- 用户ID
|
||||
-- 请求信息
|
||||
request_type VARCHAR(20) NOT NULL, -- 请求类型: chat/stream/retrieve/messages
|
||||
request_url VARCHAR(500), -- 请求URL
|
||||
request_body JSON, -- 请求体
|
||||
request_headers JSON, -- 请求头
|
||||
-- 响应信息
|
||||
response_status INT, -- HTTP状态码
|
||||
response_body JSON, -- 响应体
|
||||
response_headers JSON, -- 响应头
|
||||
-- 状态和时间
|
||||
status VARCHAR(20) NOT NULL, -- 调用状态: pending/success/failed/timeout
|
||||
start_time DATETIME NOT NULL, -- 开始时间
|
||||
end_time DATETIME, -- 结束时间
|
||||
duration_ms INT, -- 耗时(毫秒)
|
||||
-- 使用统计
|
||||
prompt_tokens INT DEFAULT 0, -- 输入Token数
|
||||
completion_tokens INT DEFAULT 0, -- 输出Token数
|
||||
total_tokens INT DEFAULT 0, -- 总Token数
|
||||
cost DECIMAL(10, 6) DEFAULT 0.000000, -- 费用
|
||||
-- 错误信息
|
||||
error_code VARCHAR(50), -- 错误代码
|
||||
error_message TEXT, -- 错误信息
|
||||
-- 公共字段
|
||||
create_by VARCHAR(36), -- 创建人ID
|
||||
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 创建时间
|
||||
update_by VARCHAR(36), -- 更新人ID
|
||||
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
|
||||
is_deleted TINYINT NOT NULL DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
|
||||
remarks VARCHAR(500) -- 备注
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'Coze API调用记录表';
|
||||
|
||||
-- ============================================================================
|
||||
-- 5. 情绪分析表 (emotion_analysis)
|
||||
-- ============================================================================
|
||||
CREATE TABLE emotion_analysis (
|
||||
id VARCHAR(36) PRIMARY KEY, -- UUID主键
|
||||
user_id VARCHAR(36) NOT NULL, -- 用户ID
|
||||
message_id VARCHAR(36), -- 关联消息ID
|
||||
text TEXT NOT NULL, -- 分析文本
|
||||
primary_emotion VARCHAR(50), -- 主要情绪
|
||||
intensity DECIMAL(3, 2), -- 情绪强度
|
||||
polarity VARCHAR(20), -- 情绪极性: positive-积极, negative-消极, neutral-中性
|
||||
confidence DECIMAL(3, 2), -- 置信度
|
||||
emotions JSON, -- 情绪分布详情
|
||||
keywords JSON, -- 关键词列表
|
||||
suggestion TEXT, -- 建议
|
||||
analysis_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 分析时间
|
||||
metadata JSON, -- 扩展元数据
|
||||
-- 公共字段
|
||||
create_by VARCHAR(36), -- 创建人ID
|
||||
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 创建时间
|
||||
update_by VARCHAR(36), -- 更新人ID
|
||||
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
|
||||
is_deleted TINYINT NOT NULL DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
|
||||
remarks VARCHAR(500) -- 备注
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '情绪分析表';
|
||||
|
||||
-- ============================================================================
|
||||
-- 6. 情绪记录表 (emotion_record)
|
||||
-- ============================================================================
|
||||
CREATE TABLE emotion_record (
|
||||
id VARCHAR(36) PRIMARY KEY, -- UUID主键
|
||||
user_id VARCHAR(36) NOT NULL, -- 用户ID
|
||||
record_date DATE NOT NULL, -- 记录日期
|
||||
emotion_type VARCHAR(50) NOT NULL, -- 情绪类型
|
||||
intensity DECIMAL(3, 2) NOT NULL, -- 情绪强度
|
||||
triggers TEXT, -- 触发因素
|
||||
description TEXT, -- 描述
|
||||
tags JSON, -- 标签
|
||||
weather VARCHAR(50), -- 天气
|
||||
location VARCHAR(100), -- 地点
|
||||
activity VARCHAR(100), -- 活动
|
||||
people VARCHAR(200), -- 相关人物
|
||||
notes TEXT, -- 备注
|
||||
-- 公共字段
|
||||
create_by VARCHAR(36), -- 创建人ID
|
||||
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 创建时间
|
||||
update_by VARCHAR(36), -- 更新人ID
|
||||
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
|
||||
is_deleted TINYINT NOT NULL DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
|
||||
remarks VARCHAR(500) -- 备注
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '情绪记录表';
|
||||
|
||||
-- ============================================================================
|
||||
-- 7. 成长课题表 (growth_topic)
|
||||
-- ============================================================================
|
||||
CREATE TABLE growth_topic (
|
||||
id VARCHAR(36) PRIMARY KEY, -- UUID主键
|
||||
title VARCHAR(100) NOT NULL, -- 课题标题
|
||||
category VARCHAR(50) NOT NULL, -- 分类
|
||||
difficulty VARCHAR(20) NOT NULL, -- 难度: easy-简单, medium-中等, hard-困难
|
||||
description TEXT, -- 描述
|
||||
content TEXT, -- 内容
|
||||
duration_days INT, -- 持续天数
|
||||
unlock_conditions JSON, -- 解锁条件
|
||||
is_unlocked TINYINT NOT NULL DEFAULT 1, -- 是否解锁
|
||||
progress DECIMAL(5, 2) NOT NULL DEFAULT 0.00, -- 进度百分比
|
||||
completed_time DATETIME, -- 完成时间
|
||||
rewards JSON, -- 奖励
|
||||
-- 公共字段
|
||||
create_by VARCHAR(36), -- 创建人ID
|
||||
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 创建时间
|
||||
update_by VARCHAR(36), -- 更新人ID
|
||||
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
|
||||
is_deleted TINYINT NOT NULL DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
|
||||
remarks VARCHAR(500) -- 备注
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '成长课题表';
|
||||
|
||||
-- ============================================================================
|
||||
-- 8. 课题互动表 (topic_interaction)
|
||||
-- ============================================================================
|
||||
CREATE TABLE topic_interaction (
|
||||
id VARCHAR(36) PRIMARY KEY, -- UUID主键
|
||||
topic_id VARCHAR(36) NOT NULL, -- 课题ID
|
||||
type VARCHAR(50) NOT NULL, -- 互动类型
|
||||
content TEXT, -- 内容
|
||||
user_input TEXT, -- 用户输入
|
||||
ai_response TEXT, -- AI回应
|
||||
rating INT, -- 评分
|
||||
feedback TEXT, -- 反馈
|
||||
completed_time DATETIME, -- 完成时间
|
||||
-- 公共字段
|
||||
create_by VARCHAR(36), -- 创建人ID
|
||||
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 创建时间
|
||||
update_by VARCHAR(36), -- 更新人ID
|
||||
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
|
||||
is_deleted TINYINT NOT NULL DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
|
||||
remarks VARCHAR(500) -- 备注
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '课题互动表';
|
||||
|
||||
-- ============================================================================
|
||||
-- 9. 地点标记表 (location_pin)
|
||||
-- ============================================================================
|
||||
CREATE TABLE location_pin (
|
||||
id VARCHAR(36) PRIMARY KEY, -- UUID主键
|
||||
name VARCHAR(100) NOT NULL, -- 地点名称
|
||||
type VARCHAR(50) NOT NULL, -- 地点类型
|
||||
category VARCHAR(50), -- 地点分类
|
||||
latitude DECIMAL(10, 8) NOT NULL, -- 纬度
|
||||
longitude DECIMAL(11, 8) NOT NULL, -- 经度
|
||||
address VARCHAR(200), -- 地址
|
||||
description TEXT, -- 描述
|
||||
created_by VARCHAR(36), -- 创建者
|
||||
likes INT NOT NULL DEFAULT 0, -- 点赞数
|
||||
visits INT NOT NULL DEFAULT 0, -- 访问数
|
||||
is_bookmarked TINYINT NOT NULL DEFAULT 0, -- 是否收藏
|
||||
last_visit_time DATETIME, -- 最后访问时间
|
||||
-- 公共字段
|
||||
create_by VARCHAR(36), -- 创建人ID
|
||||
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 创建时间
|
||||
update_by VARCHAR(36), -- 更新人ID
|
||||
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
|
||||
is_deleted TINYINT NOT NULL DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
|
||||
remarks VARCHAR(500) -- 备注
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '地点标记表';
|
||||
|
||||
-- ============================================================================
|
||||
-- 10. 社区帖子表 (community_post)
|
||||
-- ============================================================================
|
||||
CREATE TABLE community_post (
|
||||
id VARCHAR(36) PRIMARY KEY, -- UUID主键
|
||||
user_id VARCHAR(36) NOT NULL, -- 用户ID
|
||||
location_id VARCHAR(36), -- 地点ID
|
||||
title VARCHAR(200), -- 标题
|
||||
content TEXT NOT NULL, -- 内容
|
||||
type VARCHAR(50) NOT NULL, -- 帖子类型
|
||||
images JSON, -- 图片列表
|
||||
tags JSON, -- 标签
|
||||
likes INT NOT NULL DEFAULT 0, -- 点赞数
|
||||
view_count INT NOT NULL DEFAULT 0, -- 浏览数
|
||||
comment_count INT NOT NULL DEFAULT 0, -- 评论数
|
||||
is_private TINYINT NOT NULL DEFAULT 0, -- 是否私密
|
||||
-- 公共字段
|
||||
create_by VARCHAR(36), -- 创建人ID
|
||||
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 创建时间
|
||||
update_by VARCHAR(36), -- 更新人ID
|
||||
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
|
||||
is_deleted TINYINT NOT NULL DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
|
||||
remarks VARCHAR(500) -- 备注
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '社区帖子表';
|
||||
|
||||
-- ============================================================================
|
||||
-- 11. 评论表 (comment)
|
||||
-- ============================================================================
|
||||
CREATE TABLE comment (
|
||||
id VARCHAR(36) PRIMARY KEY, -- UUID主键
|
||||
post_id VARCHAR(36) NOT NULL, -- 帖子ID
|
||||
user_id VARCHAR(36) NOT NULL, -- 用户ID
|
||||
content TEXT NOT NULL, -- 评论内容
|
||||
reply_to_id VARCHAR(36), -- 回复的评论ID
|
||||
likes INT NOT NULL DEFAULT 0, -- 点赞数
|
||||
-- 公共字段
|
||||
create_by VARCHAR(36), -- 创建人ID
|
||||
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 创建时间
|
||||
update_by VARCHAR(36), -- 更新人ID
|
||||
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
|
||||
is_deleted TINYINT NOT NULL DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
|
||||
remarks VARCHAR(500) -- 备注
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '评论表';
|
||||
|
||||
-- ============================================================================
|
||||
-- 12. 成就表 (achievement)
|
||||
-- ============================================================================
|
||||
CREATE TABLE achievement (
|
||||
id VARCHAR(36) PRIMARY KEY, -- UUID主键
|
||||
title VARCHAR(100) NOT NULL, -- 成就标题
|
||||
description TEXT, -- 描述
|
||||
category VARCHAR(50) NOT NULL, -- 分类
|
||||
icon VARCHAR(200), -- 图标
|
||||
rarity VARCHAR(20) NOT NULL, -- 稀有度
|
||||
condition_type VARCHAR(50), -- 条件类型
|
||||
condition_value JSON, -- 条件值
|
||||
rewards JSON, -- 奖励
|
||||
unlocked_time DATETIME, -- 解锁时间
|
||||
progress DECIMAL(5, 2) NOT NULL DEFAULT 0.00, -- 进度
|
||||
is_hidden TINYINT NOT NULL DEFAULT 0, -- 是否隐藏
|
||||
-- 公共字段
|
||||
create_by VARCHAR(36), -- 创建人ID
|
||||
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 创建时间
|
||||
update_by VARCHAR(36), -- 更新人ID
|
||||
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
|
||||
is_deleted TINYINT NOT NULL DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
|
||||
remarks VARCHAR(500) -- 备注
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '成就表';
|
||||
|
||||
-- ============================================================================
|
||||
-- 13. 奖励表 (reward)
|
||||
-- ============================================================================
|
||||
CREATE TABLE reward (
|
||||
id VARCHAR(36) PRIMARY KEY, -- UUID主键
|
||||
topic_id VARCHAR(36), -- 课题ID
|
||||
achievement_id VARCHAR(36), -- 成就ID
|
||||
type VARCHAR(50) NOT NULL, -- 奖励类型
|
||||
name VARCHAR(100) NOT NULL, -- 奖励名称
|
||||
description TEXT, -- 描述
|
||||
icon VARCHAR(200), -- 图标
|
||||
rarity VARCHAR(20), -- 稀有度
|
||||
value JSON, -- 奖励值
|
||||
earned_time DATETIME, -- 获得时间
|
||||
is_new TINYINT NOT NULL DEFAULT 1, -- 是否新获得
|
||||
-- 公共字段
|
||||
create_by VARCHAR(36), -- 创建人ID
|
||||
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 创建时间
|
||||
update_by VARCHAR(36), -- 更新人ID
|
||||
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
|
||||
is_deleted TINYINT NOT NULL DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
|
||||
remarks VARCHAR(500) -- 备注
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '奖励表';
|
||||
|
||||
-- ============================================================================
|
||||
-- 14. 访客用户表 (guest_user)
|
||||
-- ============================================================================
|
||||
CREATE TABLE guest_user (
|
||||
id VARCHAR(36) PRIMARY KEY, -- UUID主键
|
||||
guest_user_id VARCHAR(50) NOT NULL UNIQUE, -- 访客用户ID (格式: guest_xxx)
|
||||
ip_address VARCHAR(45) NOT NULL, -- 客户端IP地址 (支持IPv6)
|
||||
user_agent TEXT, -- 用户代理信息
|
||||
nickname VARCHAR(50), -- 访客昵称
|
||||
avatar VARCHAR(500), -- 访客头像
|
||||
last_active_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 最后活跃时间
|
||||
conversation_count INT NOT NULL DEFAULT 0, -- 会话数量
|
||||
message_count INT NOT NULL DEFAULT 0, -- 消息数量
|
||||
location VARCHAR(100), -- IP地址的地理位置信息
|
||||
device_info VARCHAR(200), -- 设备信息
|
||||
-- 公共字段
|
||||
create_by VARCHAR(36), -- 创建人ID
|
||||
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 创建时间
|
||||
update_by VARCHAR(36), -- 更新人ID
|
||||
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
|
||||
is_deleted TINYINT NOT NULL DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
|
||||
remarks VARCHAR(500) -- 备注
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '访客用户表';
|
||||
|
||||
-- ============================================================================
|
||||
-- 15. 用户统计表 (user_stats)
|
||||
-- ============================================================================
|
||||
CREATE TABLE user_stats (
|
||||
id VARCHAR(36) PRIMARY KEY, -- UUID主键
|
||||
user_id VARCHAR(36) NOT NULL UNIQUE, -- 用户ID
|
||||
total_conversations INT NOT NULL DEFAULT 0, -- 总对话数
|
||||
total_messages INT NOT NULL DEFAULT 0, -- 总消息数
|
||||
total_emotions_recorded INT NOT NULL DEFAULT 0, -- 总情绪记录数
|
||||
topics_completed INT NOT NULL DEFAULT 0, -- 完成的课题数
|
||||
achievements_unlocked INT NOT NULL DEFAULT 0, -- 解锁的成就数
|
||||
total_points INT NOT NULL DEFAULT 0, -- 总积分
|
||||
consecutive_days INT NOT NULL DEFAULT 0, -- 连续使用天数
|
||||
max_consecutive_days INT NOT NULL DEFAULT 0, -- 最大连续天数
|
||||
locations_visited INT NOT NULL DEFAULT 0, -- 访问的地点数
|
||||
posts_created INT NOT NULL DEFAULT 0, -- 创建的帖子数
|
||||
comments_made INT NOT NULL DEFAULT 0, -- 评论数
|
||||
likes_received INT NOT NULL DEFAULT 0, -- 收到的点赞数
|
||||
social_interactions INT NOT NULL DEFAULT 0, -- 社交互动数
|
||||
-- 公共字段
|
||||
create_by VARCHAR(36), -- 创建人ID
|
||||
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 创建时间
|
||||
update_by VARCHAR(36), -- 更新人ID
|
||||
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
|
||||
is_deleted TINYINT NOT NULL DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
|
||||
remarks VARCHAR(500) -- 备注
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户统计表';
|
||||
|
||||
-- ============================================================================
|
||||
-- 创建索引以提高查询性能
|
||||
-- 注意: MySQL的CREATE INDEX不支持IF NOT EXISTS
|
||||
-- 如果索引已存在,重复执行会产生警告但不会中断脚本执行
|
||||
-- ============================================================================
|
||||
-- user表索引
|
||||
CREATE INDEX idx_user_account ON user (account);
|
||||
|
||||
CREATE INDEX idx_user_username ON user (username);
|
||||
|
||||
CREATE INDEX idx_user_email ON user (email);
|
||||
|
||||
CREATE INDEX idx_user_phone ON user (phone);
|
||||
|
||||
CREATE INDEX idx_user_last_active_time ON user (last_active_time);
|
||||
|
||||
CREATE INDEX idx_user_create_time ON user (create_time);
|
||||
|
||||
CREATE INDEX idx_user_member_level ON user (member_level);
|
||||
|
||||
CREATE INDEX idx_user_status ON user (status);
|
||||
|
||||
CREATE INDEX idx_user_is_verified ON user (is_verified);
|
||||
|
||||
CREATE INDEX idx_user_create_by ON user (create_by);
|
||||
|
||||
CREATE INDEX idx_user_update_by ON user (update_by);
|
||||
|
||||
CREATE INDEX idx_user_is_deleted ON user (is_deleted);
|
||||
|
||||
-- conversation表索引
|
||||
CREATE INDEX idx_conversation_user_id ON conversation (user_id);
|
||||
|
||||
CREATE INDEX idx_conversation_start_time ON conversation (start_time);
|
||||
|
||||
CREATE INDEX idx_conversation_user_id_start_time ON conversation (user_id, start_time);
|
||||
|
||||
CREATE INDEX idx_conversation_primary_emotion ON conversation (primary_emotion);
|
||||
|
||||
CREATE INDEX idx_conversation_end_time ON conversation (end_time);
|
||||
|
||||
CREATE INDEX idx_conversation_create_time ON conversation (create_time);
|
||||
|
||||
CREATE INDEX idx_conversation_coze_conversation_id ON conversation (coze_conversation_id);
|
||||
|
||||
CREATE INDEX idx_conversation_status ON conversation (status);
|
||||
|
||||
CREATE INDEX idx_conversation_last_active_time ON conversation (last_active_time);
|
||||
|
||||
CREATE INDEX idx_conversation_create_by ON conversation (create_by);
|
||||
|
||||
CREATE INDEX idx_conversation_update_by ON conversation (update_by);
|
||||
|
||||
CREATE INDEX idx_conversation_is_deleted ON conversation (is_deleted);
|
||||
|
||||
CREATE INDEX idx_conversation_user_type ON conversation (user_type);
|
||||
|
||||
CREATE INDEX idx_conversation_emotion_trend ON conversation (emotion_trend);
|
||||
|
||||
CREATE INDEX idx_conversation_confidence ON conversation (confidence);
|
||||
|
||||
CREATE INDEX idx_conversation_client_ip ON conversation (client_ip);
|
||||
|
||||
-- message表索引
|
||||
CREATE INDEX idx_message_conversation_id ON message (conversation_id);
|
||||
|
||||
CREATE INDEX idx_message_timestamp ON message (timestamp);
|
||||
|
||||
CREATE INDEX idx_message_conversation_id_timestamp ON message (conversation_id, timestamp);
|
||||
|
||||
CREATE INDEX idx_message_sender ON message (sender);
|
||||
|
||||
CREATE INDEX idx_message_type ON message (type);
|
||||
|
||||
CREATE INDEX idx_message_is_read ON message (is_read);
|
||||
|
||||
CREATE INDEX idx_message_create_time ON message (create_time);
|
||||
|
||||
CREATE INDEX idx_message_coze_chat_id ON message (coze_chat_id);
|
||||
|
||||
CREATE INDEX idx_message_status ON message (status);
|
||||
|
||||
CREATE INDEX idx_message_parent_message_id ON message (parent_message_id);
|
||||
|
||||
CREATE INDEX idx_message_create_by ON message (create_by);
|
||||
|
||||
CREATE INDEX idx_message_update_by ON message (update_by);
|
||||
|
||||
CREATE INDEX idx_message_is_deleted ON message (is_deleted);
|
||||
|
||||
-- coze_api_call表索引
|
||||
CREATE INDEX idx_coze_api_call_conversation_id ON coze_api_call (conversation_id);
|
||||
|
||||
CREATE INDEX idx_coze_api_call_message_id ON coze_api_call (message_id);
|
||||
|
||||
CREATE INDEX idx_coze_api_call_coze_chat_id ON coze_api_call (coze_chat_id);
|
||||
|
||||
CREATE INDEX idx_coze_api_call_bot_id ON coze_api_call (bot_id);
|
||||
|
||||
CREATE INDEX idx_coze_api_call_user_id ON coze_api_call (user_id);
|
||||
|
||||
CREATE INDEX idx_coze_api_call_status ON coze_api_call (status);
|
||||
|
||||
CREATE INDEX idx_coze_api_call_start_time ON coze_api_call (start_time);
|
||||
|
||||
-- emotion_analysis表索引
|
||||
CREATE INDEX idx_emotion_analysis_user_id ON emotion_analysis (user_id);
|
||||
|
||||
CREATE INDEX idx_emotion_analysis_message_id ON emotion_analysis (message_id);
|
||||
|
||||
CREATE INDEX idx_emotion_analysis_primary_emotion ON emotion_analysis (primary_emotion);
|
||||
|
||||
CREATE INDEX idx_emotion_analysis_analysis_time ON emotion_analysis (analysis_time);
|
||||
|
||||
CREATE INDEX idx_emotion_analysis_create_time ON emotion_analysis (create_time);
|
||||
|
||||
CREATE INDEX idx_emotion_analysis_create_by ON emotion_analysis (create_by);
|
||||
|
||||
CREATE INDEX idx_emotion_analysis_update_by ON emotion_analysis (update_by);
|
||||
|
||||
CREATE INDEX idx_emotion_analysis_is_deleted ON emotion_analysis (is_deleted);
|
||||
|
||||
-- emotion_record表索引
|
||||
CREATE INDEX idx_emotion_record_user_id ON emotion_record (user_id);
|
||||
|
||||
CREATE INDEX idx_emotion_record_date ON emotion_record (record_date);
|
||||
|
||||
CREATE INDEX idx_emotion_record_emotion_type ON emotion_record (emotion_type);
|
||||
|
||||
CREATE INDEX idx_emotion_record_user_id_date ON emotion_record (user_id, record_date);
|
||||
|
||||
CREATE INDEX idx_emotion_record_user_id_emotion_type ON emotion_record (user_id, emotion_type);
|
||||
|
||||
CREATE INDEX idx_emotion_record_intensity ON emotion_record (intensity);
|
||||
|
||||
CREATE INDEX idx_emotion_record_create_time ON emotion_record (create_time);
|
||||
|
||||
CREATE INDEX idx_emotion_record_create_by ON emotion_record (create_by);
|
||||
|
||||
CREATE INDEX idx_emotion_record_update_by ON emotion_record (update_by);
|
||||
|
||||
CREATE INDEX idx_emotion_record_is_deleted ON emotion_record (is_deleted);
|
||||
|
||||
-- growth_topic表索引
|
||||
CREATE INDEX idx_growth_topic_category ON growth_topic (category);
|
||||
|
||||
CREATE INDEX idx_growth_topic_difficulty ON growth_topic (difficulty);
|
||||
|
||||
CREATE INDEX idx_growth_topic_is_unlocked ON growth_topic (is_unlocked);
|
||||
|
||||
CREATE INDEX idx_growth_topic_progress ON growth_topic (progress);
|
||||
|
||||
CREATE INDEX idx_growth_topic_completed_time ON growth_topic (completed_time);
|
||||
|
||||
CREATE INDEX idx_growth_topic_category_difficulty ON growth_topic (category, difficulty);
|
||||
|
||||
CREATE INDEX idx_growth_topic_create_time ON growth_topic (create_time);
|
||||
|
||||
-- topic_interaction表索引
|
||||
CREATE INDEX idx_topic_interaction_topic_id ON topic_interaction (topic_id);
|
||||
|
||||
CREATE INDEX idx_topic_interaction_type ON topic_interaction (type);
|
||||
|
||||
CREATE INDEX idx_topic_interaction_completed_time ON topic_interaction (completed_time);
|
||||
|
||||
CREATE INDEX idx_topic_interaction_rating ON topic_interaction (rating);
|
||||
|
||||
CREATE INDEX idx_topic_interaction_topic_id_type ON topic_interaction (topic_id, type);
|
||||
|
||||
CREATE INDEX idx_topic_interaction_create_time ON topic_interaction (create_time);
|
||||
|
||||
-- location_pin表索引
|
||||
CREATE INDEX idx_location_pin_latitude_longitude ON location_pin (latitude, longitude);
|
||||
|
||||
CREATE INDEX idx_location_pin_type ON location_pin (type);
|
||||
|
||||
CREATE INDEX idx_location_pin_category ON location_pin (category);
|
||||
|
||||
CREATE INDEX idx_location_pin_created_by ON location_pin (created_by);
|
||||
|
||||
CREATE INDEX idx_location_pin_likes ON location_pin (likes);
|
||||
|
||||
CREATE INDEX idx_location_pin_visits ON location_pin (visits);
|
||||
|
||||
CREATE INDEX idx_location_pin_is_bookmarked ON location_pin (is_bookmarked);
|
||||
|
||||
CREATE INDEX idx_location_pin_type_category ON location_pin (type, category);
|
||||
|
||||
CREATE INDEX idx_location_pin_create_time ON location_pin (create_time);
|
||||
|
||||
CREATE INDEX idx_location_pin_last_visit_time ON location_pin (last_visit_time);
|
||||
|
||||
-- community_post表索引
|
||||
CREATE INDEX idx_community_post_user_id ON community_post (user_id);
|
||||
|
||||
CREATE INDEX idx_community_post_location_id ON community_post (location_id);
|
||||
|
||||
CREATE INDEX idx_community_post_create_time ON community_post (create_time);
|
||||
|
||||
CREATE INDEX idx_community_post_type ON community_post (type);
|
||||
|
||||
CREATE INDEX idx_community_post_likes ON community_post (likes);
|
||||
|
||||
CREATE INDEX idx_community_post_view_count ON community_post (view_count);
|
||||
|
||||
CREATE INDEX idx_community_post_is_private ON community_post (is_private);
|
||||
|
||||
CREATE INDEX idx_community_post_user_id_create_time ON community_post (user_id, create_time);
|
||||
|
||||
CREATE INDEX idx_community_post_type_create_time ON community_post (type, create_time);
|
||||
|
||||
-- comment表索引
|
||||
CREATE INDEX idx_comment_post_id ON comment (post_id);
|
||||
|
||||
CREATE INDEX idx_comment_user_id ON comment (user_id);
|
||||
|
||||
CREATE INDEX idx_comment_reply_to_id ON comment (reply_to_id);
|
||||
|
||||
CREATE INDEX idx_comment_create_time ON comment (create_time);
|
||||
|
||||
CREATE INDEX idx_comment_likes ON comment (likes);
|
||||
|
||||
CREATE INDEX idx_comment_post_id_create_time ON comment (post_id, create_time);
|
||||
|
||||
-- achievement表索引
|
||||
CREATE INDEX idx_achievement_category ON achievement (category);
|
||||
|
||||
CREATE INDEX idx_achievement_rarity ON achievement (rarity);
|
||||
|
||||
CREATE INDEX idx_achievement_unlocked_time ON achievement (unlocked_time);
|
||||
|
||||
CREATE INDEX idx_achievement_is_hidden ON achievement (is_hidden);
|
||||
|
||||
CREATE INDEX idx_achievement_progress ON achievement (progress);
|
||||
|
||||
CREATE INDEX idx_achievement_category_rarity ON achievement (category, rarity);
|
||||
|
||||
CREATE INDEX idx_achievement_create_time ON achievement (create_time);
|
||||
|
||||
-- reward表索引
|
||||
CREATE INDEX idx_reward_topic_id ON reward (topic_id);
|
||||
|
||||
CREATE INDEX idx_reward_achievement_id ON reward (achievement_id);
|
||||
|
||||
CREATE INDEX idx_reward_type ON reward (type);
|
||||
|
||||
CREATE INDEX idx_reward_earned_time ON reward (earned_time);
|
||||
|
||||
CREATE INDEX idx_reward_rarity ON reward (rarity);
|
||||
|
||||
CREATE INDEX idx_reward_is_new ON reward (is_new);
|
||||
|
||||
CREATE INDEX idx_reward_type_earned_time ON reward (type, earned_time);
|
||||
|
||||
CREATE INDEX idx_reward_create_time ON reward (create_time);
|
||||
|
||||
-- user_stats表索引
|
||||
CREATE INDEX idx_user_stats_user_id ON user_stats (user_id);
|
||||
|
||||
CREATE INDEX idx_user_stats_total_points ON user_stats (total_points);
|
||||
|
||||
CREATE INDEX idx_user_stats_consecutive_days ON user_stats (consecutive_days);
|
||||
|
||||
CREATE INDEX idx_user_stats_max_consecutive_days ON user_stats (max_consecutive_days);
|
||||
|
||||
CREATE INDEX idx_user_stats_social_interactions ON user_stats (social_interactions);
|
||||
|
||||
CREATE INDEX idx_user_stats_update_time ON user_stats (update_time);
|
||||
|
||||
CREATE INDEX idx_user_stats_create_time ON user_stats (create_time);
|
||||
|
||||
-- guest_user表索引
|
||||
CREATE INDEX idx_guest_user_guest_user_id ON guest_user (guest_user_id);
|
||||
|
||||
CREATE INDEX idx_guest_user_ip_address ON guest_user (ip_address);
|
||||
|
||||
CREATE INDEX idx_guest_user_last_active_time ON guest_user (last_active_time);
|
||||
|
||||
CREATE INDEX idx_guest_user_conversation_count ON guest_user (conversation_count);
|
||||
|
||||
CREATE INDEX idx_guest_user_message_count ON guest_user (message_count);
|
||||
|
||||
CREATE INDEX idx_guest_user_create_time ON guest_user (create_time);
|
||||
|
||||
CREATE INDEX idx_guest_user_create_by ON guest_user (create_by);
|
||||
|
||||
CREATE INDEX idx_guest_user_update_by ON guest_user (update_by);
|
||||
|
||||
CREATE INDEX idx_guest_user_is_deleted ON guest_user (is_deleted);
|
||||
|
||||
-- ============================================================================
|
||||
-- 数据库统计信息
|
||||
-- ============================================================================
|
||||
SELECT
|
||||
COUNT(*) as total_tables
|
||||
FROM
|
||||
INFORMATION_SCHEMA.TABLES
|
||||
WHERE
|
||||
TABLE_SCHEMA = 'emotion_museum';
|
||||
|
||||
-- 显示创建的表
|
||||
SELECT
|
||||
TABLE_NAME as table_name,
|
||||
TABLE_COMMENT as comment,
|
||||
ENGINE as engine
|
||||
FROM
|
||||
INFORMATION_SCHEMA.TABLES
|
||||
WHERE
|
||||
TABLE_SCHEMA = 'emotion_museum'
|
||||
ORDER BY
|
||||
TABLE_NAME;
|
||||
|
||||
-- 提交事务
|
||||
COMMIT;
|
||||
|
||||
-- 完成消息
|
||||
SELECT
|
||||
'Emotion Museum Database v3.0 Final (雪花算法主键版本) - 开发版本 deployment completed successfully!' as message,
|
||||
NOW () as completion_time,
|
||||
'All tables dropped and recreated with VARCHAR(36) primary keys. Development version - data will be lost on re-execution!' as description;
|
||||
@@ -0,0 +1,81 @@
|
||||
-- ============================================================================
|
||||
-- 数据库脚本验证查询
|
||||
-- 用于验证 mysql_emotion_museum_final.sql 执行后的表结构
|
||||
-- ============================================================================
|
||||
|
||||
-- 验证数据库是否存在
|
||||
SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = 'emotion_museum';
|
||||
|
||||
-- 验证所有表是否创建成功
|
||||
SELECT TABLE_NAME, TABLE_COMMENT
|
||||
FROM INFORMATION_SCHEMA.TABLES
|
||||
WHERE TABLE_SCHEMA = 'emotion_museum'
|
||||
ORDER BY TABLE_NAME;
|
||||
|
||||
-- 验证conversation表的字段结构(重点验证新增字段)
|
||||
SELECT
|
||||
COLUMN_NAME,
|
||||
DATA_TYPE,
|
||||
IS_NULLABLE,
|
||||
COLUMN_DEFAULT,
|
||||
COLUMN_COMMENT
|
||||
FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE TABLE_SCHEMA = 'emotion_museum'
|
||||
AND TABLE_NAME = 'conversation'
|
||||
ORDER BY ORDINAL_POSITION;
|
||||
|
||||
-- 验证conversation表的索引
|
||||
SELECT
|
||||
INDEX_NAME,
|
||||
COLUMN_NAME,
|
||||
NON_UNIQUE
|
||||
FROM INFORMATION_SCHEMA.STATISTICS
|
||||
WHERE TABLE_SCHEMA = 'emotion_museum'
|
||||
AND TABLE_NAME = 'conversation'
|
||||
ORDER BY INDEX_NAME, SEQ_IN_INDEX;
|
||||
|
||||
-- 验证新增字段是否存在
|
||||
SELECT
|
||||
CASE
|
||||
WHEN COUNT(*) = 9 THEN '✅ 所有新增字段都存在'
|
||||
ELSE CONCAT('❌ 缺少字段,只找到 ', COUNT(*), ' 个,应该是 9 个')
|
||||
END AS validation_result
|
||||
FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE TABLE_SCHEMA = 'emotion_museum'
|
||||
AND TABLE_NAME = 'conversation'
|
||||
AND COLUMN_NAME IN (
|
||||
'user_type', 'emotion_trend', 'keywords', 'ai_insights',
|
||||
'confidence', 'client_ip', 'user_agent', 'summary', 'tags'
|
||||
);
|
||||
|
||||
-- 验证新增索引是否存在
|
||||
SELECT
|
||||
CASE
|
||||
WHEN COUNT(*) = 4 THEN '✅ 所有新增索引都存在'
|
||||
ELSE CONCAT('❌ 缺少索引,只找到 ', COUNT(*), ' 个,应该是 4 个')
|
||||
END AS index_validation_result
|
||||
FROM INFORMATION_SCHEMA.STATISTICS
|
||||
WHERE TABLE_SCHEMA = 'emotion_museum'
|
||||
AND TABLE_NAME = 'conversation'
|
||||
AND INDEX_NAME IN (
|
||||
'idx_conversation_user_type',
|
||||
'idx_conversation_emotion_trend',
|
||||
'idx_conversation_confidence',
|
||||
'idx_conversation_client_ip'
|
||||
);
|
||||
|
||||
-- 统计总表数
|
||||
SELECT
|
||||
CASE
|
||||
WHEN COUNT(*) = 15 THEN '✅ 所有15个表都创建成功'
|
||||
ELSE CONCAT('❌ 表数量不正确,只有 ', COUNT(*), ' 个表,应该是 15 个')
|
||||
END AS table_count_result
|
||||
FROM INFORMATION_SCHEMA.TABLES
|
||||
WHERE TABLE_SCHEMA = 'emotion_museum';
|
||||
|
||||
-- 统计总索引数(conversation表)
|
||||
SELECT
|
||||
CONCAT('conversation表共有 ', COUNT(DISTINCT INDEX_NAME), ' 个索引') AS conversation_index_count
|
||||
FROM INFORMATION_SCHEMA.STATISTICS
|
||||
WHERE TABLE_SCHEMA = 'emotion_museum'
|
||||
AND TABLE_NAME = 'conversation';
|
||||
+1014
File diff suppressed because it is too large
Load Diff
+114
@@ -0,0 +1,114 @@
|
||||
# 情绪博物馆主站配置
|
||||
server {
|
||||
listen 80;
|
||||
server_name localhost emotion-museum.com www.emotion-museum.com;
|
||||
|
||||
# 安全头
|
||||
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;
|
||||
|
||||
# API代理
|
||||
location /api/ {
|
||||
# 限流
|
||||
limit_req zone=api burst=20 nodelay;
|
||||
|
||||
# 代理到网关
|
||||
proxy_pass http://emotion_gateway;
|
||||
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;
|
||||
|
||||
# 超时设置
|
||||
proxy_connect_timeout 30s;
|
||||
proxy_send_timeout 30s;
|
||||
proxy_read_timeout 30s;
|
||||
|
||||
# 缓存控制
|
||||
proxy_cache_bypass $http_upgrade;
|
||||
proxy_no_cache $http_upgrade;
|
||||
|
||||
# WebSocket支持
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
}
|
||||
|
||||
# 静态资源代理
|
||||
location / {
|
||||
# 限流
|
||||
limit_req zone=web burst=50 nodelay;
|
||||
|
||||
# 代理到前端应用
|
||||
proxy_pass http://emotion_web;
|
||||
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 ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
|
||||
proxy_pass http://emotion_web;
|
||||
proxy_set_header Host $host;
|
||||
expires 30d;
|
||||
add_header Cache-Control "public, immutable";
|
||||
add_header Vary "Accept-Encoding";
|
||||
}
|
||||
|
||||
# HTML文件不缓存
|
||||
location ~* \.(html|htm)$ {
|
||||
proxy_pass http://emotion_web;
|
||||
proxy_set_header Host $host;
|
||||
expires -1;
|
||||
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
||||
add_header Pragma "no-cache";
|
||||
}
|
||||
}
|
||||
|
||||
# 健康检查
|
||||
location /nginx-health {
|
||||
access_log off;
|
||||
return 200 "healthy\n";
|
||||
add_header Content-Type text/plain;
|
||||
}
|
||||
|
||||
# 错误页面
|
||||
error_page 404 /404.html;
|
||||
error_page 500 502 503 504 /50x.html;
|
||||
|
||||
location = /50x.html {
|
||||
root /usr/share/nginx/html;
|
||||
}
|
||||
}
|
||||
|
||||
# HTTPS配置 (可选)
|
||||
# server {
|
||||
# listen 443 ssl http2;
|
||||
# server_name emotion-museum.com www.emotion-museum.com;
|
||||
#
|
||||
# # SSL证书配置
|
||||
# ssl_certificate /etc/nginx/ssl/emotion-museum.crt;
|
||||
# ssl_certificate_key /etc/nginx/ssl/emotion-museum.key;
|
||||
#
|
||||
# # SSL安全配置
|
||||
# ssl_protocols TLSv1.2 TLSv1.3;
|
||||
# ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384;
|
||||
# ssl_prefer_server_ciphers off;
|
||||
# ssl_session_cache shared:SSL:10m;
|
||||
# ssl_session_timeout 10m;
|
||||
#
|
||||
# # HSTS
|
||||
# add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
|
||||
#
|
||||
# # 其他配置与HTTP相同
|
||||
# include /etc/nginx/conf.d/emotion-museum-common.conf;
|
||||
# }
|
||||
|
||||
# HTTP重定向到HTTPS (可选)
|
||||
# server {
|
||||
# listen 80;
|
||||
# server_name emotion-museum.com www.emotion-museum.com;
|
||||
# return 301 https://$server_name$request_uri;
|
||||
# }
|
||||
@@ -0,0 +1,81 @@
|
||||
user nginx;
|
||||
worker_processes auto;
|
||||
error_log /var/log/nginx/error.log notice;
|
||||
pid /var/run/nginx.pid;
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
use epoll;
|
||||
multi_accept on;
|
||||
}
|
||||
|
||||
http {
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
# 日志格式
|
||||
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||
'$status $body_bytes_sent "$http_referer" '
|
||||
'"$http_user_agent" "$http_x_forwarded_for" '
|
||||
'$request_time $upstream_response_time';
|
||||
|
||||
access_log /var/log/nginx/access.log main;
|
||||
|
||||
# 基础配置
|
||||
sendfile on;
|
||||
tcp_nopush on;
|
||||
tcp_nodelay on;
|
||||
keepalive_timeout 65;
|
||||
types_hash_max_size 2048;
|
||||
server_tokens off;
|
||||
|
||||
# Gzip压缩
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
gzip_min_length 1024;
|
||||
gzip_proxied any;
|
||||
gzip_comp_level 6;
|
||||
gzip_types
|
||||
text/plain
|
||||
text/css
|
||||
text/xml
|
||||
text/javascript
|
||||
application/json
|
||||
application/javascript
|
||||
application/xml+rss
|
||||
application/atom+xml
|
||||
image/svg+xml;
|
||||
|
||||
# 客户端配置
|
||||
client_max_body_size 50M;
|
||||
client_body_buffer_size 128k;
|
||||
client_header_buffer_size 32k;
|
||||
large_client_header_buffers 4 32k;
|
||||
|
||||
# 代理配置
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_send_timeout 60s;
|
||||
proxy_read_timeout 60s;
|
||||
proxy_buffer_size 64k;
|
||||
proxy_buffers 4 64k;
|
||||
proxy_busy_buffers_size 128k;
|
||||
proxy_temp_file_write_size 128k;
|
||||
|
||||
# 上游服务器定义
|
||||
upstream emotion_gateway {
|
||||
server gateway:9000 max_fails=3 fail_timeout=30s;
|
||||
keepalive 32;
|
||||
}
|
||||
|
||||
upstream emotion_web {
|
||||
server web:80 max_fails=3 fail_timeout=30s;
|
||||
keepalive 32;
|
||||
}
|
||||
|
||||
# 限流配置
|
||||
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
|
||||
limit_req_zone $binary_remote_addr zone=web:10m rate=20r/s;
|
||||
|
||||
# 包含站点配置
|
||||
include /etc/nginx/conf.d/*.conf;
|
||||
}
|
||||
@@ -0,0 +1,233 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
# MySQL数据库
|
||||
mysql:
|
||||
image: mysql:8.0
|
||||
container_name: emotion-mysql
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-123456}
|
||||
MYSQL_DATABASE: ${MYSQL_DATABASE:-emotion_museum}
|
||||
MYSQL_USER: ${MYSQL_USERNAME:-emotion}
|
||||
MYSQL_PASSWORD: ${MYSQL_PASSWORD:-emotion123}
|
||||
TZ: ${TZ:-Asia/Shanghai}
|
||||
ports:
|
||||
- "${MYSQL_PORT:-3306}:3306"
|
||||
volumes:
|
||||
- mysql_data:/var/lib/mysql
|
||||
- ./database/mysql_emotion_museum_final.sql:/docker-entrypoint-initdb.d/01-init.sql
|
||||
- ./deploy/mysql/conf.d:/etc/mysql/conf.d
|
||||
command: >
|
||||
--default-authentication-plugin=mysql_native_password
|
||||
--character-set-server=utf8mb4
|
||||
--collation-server=utf8mb4_unicode_ci
|
||||
--default-time-zone='+8:00'
|
||||
--max-connections=1000
|
||||
--max-allowed-packet=64M
|
||||
networks:
|
||||
- emotion-network
|
||||
healthcheck:
|
||||
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p${MYSQL_ROOT_PASSWORD:-123456}"]
|
||||
timeout: 20s
|
||||
retries: 10
|
||||
|
||||
# Redis缓存
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
container_name: emotion-redis
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "${REDIS_PORT:-6379}:6379"
|
||||
volumes:
|
||||
- redis_data:/data
|
||||
- ./deploy/redis/redis.conf:/usr/local/etc/redis/redis.conf
|
||||
command: redis-server /usr/local/etc/redis/redis.conf
|
||||
networks:
|
||||
- emotion-network
|
||||
healthcheck:
|
||||
test: ["CMD", "redis-cli", "ping"]
|
||||
timeout: 3s
|
||||
retries: 5
|
||||
|
||||
# 网关服务
|
||||
gateway:
|
||||
build:
|
||||
context: ./backend
|
||||
dockerfile: gateway-Dockerfile
|
||||
args:
|
||||
JAR_FILE: emotion-gateway-1.0.0.jar
|
||||
CONFIG_FILE: config/gateway-test.yml
|
||||
container_name: emotion-gateway
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "${GATEWAY_PORT:-9000}:9000"
|
||||
environment:
|
||||
SPRING_PROFILES_ACTIVE: test
|
||||
NACOS_SERVER_ADDR: ${NACOS_SERVER_ADDR:-localhost:8848}
|
||||
MYSQL_HOST: mysql
|
||||
MYSQL_PORT: 3306
|
||||
MYSQL_USERNAME: ${MYSQL_USERNAME:-emotion}
|
||||
MYSQL_PASSWORD: ${MYSQL_PASSWORD:-emotion123}
|
||||
REDIS_HOST: redis
|
||||
REDIS_PORT: 6379
|
||||
SERVER_IP: ${SERVER_IP:-localhost}
|
||||
JWT_SECRET: ${JWT_SECRET:-emotion-museum-test-secret-key-2025}
|
||||
TZ: ${TZ:-Asia/Shanghai}
|
||||
depends_on:
|
||||
mysql:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
networks:
|
||||
- emotion-network
|
||||
volumes:
|
||||
- ${LOG_PATH:-./logs}:/data/logs/emotion-museum
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:9000/actuator/health"]
|
||||
timeout: 10s
|
||||
retries: 5
|
||||
start_period: 60s
|
||||
|
||||
# 用户服务
|
||||
user-service:
|
||||
build:
|
||||
context: ./backend
|
||||
dockerfile: user-Dockerfile
|
||||
args:
|
||||
JAR_FILE: emotion-user-1.0.0.jar
|
||||
CONFIG_FILE: config/application-test.yml
|
||||
container_name: emotion-user
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "${USER_SERVICE_PORT:-9001}:9001"
|
||||
environment:
|
||||
SPRING_PROFILES_ACTIVE: test
|
||||
NACOS_SERVER_ADDR: ${NACOS_SERVER_ADDR:-localhost:8848}
|
||||
MYSQL_HOST: mysql
|
||||
MYSQL_PORT: 3306
|
||||
MYSQL_USERNAME: ${MYSQL_USERNAME:-emotion}
|
||||
MYSQL_PASSWORD: ${MYSQL_PASSWORD:-emotion123}
|
||||
REDIS_HOST: redis
|
||||
REDIS_PORT: 6379
|
||||
SERVER_IP: ${SERVER_IP:-localhost}
|
||||
JWT_SECRET: ${JWT_SECRET:-emotion-museum-test-secret-key-2025}
|
||||
TZ: ${TZ:-Asia/Shanghai}
|
||||
depends_on:
|
||||
mysql:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
networks:
|
||||
- emotion-network
|
||||
volumes:
|
||||
- ${LOG_PATH:-./logs}:/data/logs/emotion-museum
|
||||
- ${UPLOAD_PATH:-./uploads}:/data/uploads/emotion-museum
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:9001/actuator/health"]
|
||||
timeout: 10s
|
||||
retries: 5
|
||||
start_period: 60s
|
||||
|
||||
# AI服务
|
||||
ai-service:
|
||||
build:
|
||||
context: ./backend
|
||||
dockerfile: ai-Dockerfile
|
||||
args:
|
||||
JAR_FILE: emotion-ai-1.0.0.jar
|
||||
CONFIG_FILE: config/ai-test.yml
|
||||
container_name: emotion-ai
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "${AI_SERVICE_PORT:-9002}:9002"
|
||||
environment:
|
||||
SPRING_PROFILES_ACTIVE: test
|
||||
NACOS_SERVER_ADDR: ${NACOS_SERVER_ADDR:-localhost:8848}
|
||||
MYSQL_HOST: mysql
|
||||
MYSQL_PORT: 3306
|
||||
MYSQL_USERNAME: ${MYSQL_USERNAME:-emotion}
|
||||
MYSQL_PASSWORD: ${MYSQL_PASSWORD:-emotion123}
|
||||
REDIS_HOST: redis
|
||||
REDIS_PORT: 6379
|
||||
SERVER_IP: ${SERVER_IP:-localhost}
|
||||
COZE_API_TOKEN: ${COZE_API_TOKEN:-your-coze-api-token}
|
||||
JWT_SECRET: ${JWT_SECRET:-emotion-museum-test-secret-key-2025}
|
||||
TZ: ${TZ:-Asia/Shanghai}
|
||||
depends_on:
|
||||
mysql:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
networks:
|
||||
- emotion-network
|
||||
volumes:
|
||||
- ${LOG_PATH:-./logs}:/data/logs/emotion-museum
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:9002/actuator/health"]
|
||||
timeout: 10s
|
||||
retries: 5
|
||||
start_period: 60s
|
||||
|
||||
# 前端应用
|
||||
web:
|
||||
build:
|
||||
context: ./frontend
|
||||
dockerfile: Dockerfile
|
||||
args:
|
||||
NODE_ENV: test
|
||||
VUE_APP_API_BASE_URL: http://${SERVER_IP:-localhost}:${GATEWAY_PORT:-9000}
|
||||
VUE_APP_ENVIRONMENT: test
|
||||
container_name: emotion-web
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "${WEB_PORT:-3000}:80"
|
||||
environment:
|
||||
TZ: ${TZ:-Asia/Shanghai}
|
||||
depends_on:
|
||||
gateway:
|
||||
condition: service_healthy
|
||||
networks:
|
||||
- emotion-network
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:80/"]
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
|
||||
# Nginx反向代理
|
||||
nginx:
|
||||
image: nginx:alpine
|
||||
container_name: emotion-nginx
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "${NGINX_PORT:-80}:80"
|
||||
volumes:
|
||||
- ./deploy/nginx/conf.d:/etc/nginx/conf.d
|
||||
- nginx_logs:/var/log/nginx
|
||||
environment:
|
||||
TZ: ${TZ:-Asia/Shanghai}
|
||||
depends_on:
|
||||
- web
|
||||
- gateway
|
||||
networks:
|
||||
- emotion-network
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:80/health"]
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
|
||||
volumes:
|
||||
mysql_data:
|
||||
driver: local
|
||||
redis_data:
|
||||
driver: local
|
||||
nginx_logs:
|
||||
driver: local
|
||||
|
||||
networks:
|
||||
emotion-network:
|
||||
driver: bridge
|
||||
ipam:
|
||||
config:
|
||||
- subnet: ${SUBNET:-172.20.0.0/16}
|
||||
gateway: ${GATEWAY_IP:-172.20.0.1}
|
||||
@@ -0,0 +1,178 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
# MySQL数据库
|
||||
mysql:
|
||||
image: mysql:8.0
|
||||
container_name: emotion-mysql
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: 123456
|
||||
MYSQL_DATABASE: emotion_museum
|
||||
MYSQL_USER: emotion
|
||||
MYSQL_PASSWORD: emotion123
|
||||
TZ: Asia/Shanghai
|
||||
ports:
|
||||
- "3306:3306"
|
||||
volumes:
|
||||
- mysql_data:/var/lib/mysql
|
||||
- ./backend/mysql_emotion_museum_final.sql:/docker-entrypoint-initdb.d/init.sql
|
||||
- ./deploy/mysql/conf.d:/etc/mysql/conf.d
|
||||
command: --default-authentication-plugin=mysql_native_password
|
||||
networks:
|
||||
- emotion-network
|
||||
|
||||
# Redis缓存
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
container_name: emotion-redis
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "6379:6379"
|
||||
volumes:
|
||||
- redis_data:/data
|
||||
- ./deploy/redis/redis.conf:/usr/local/etc/redis/redis.conf
|
||||
command: redis-server /usr/local/etc/redis/redis.conf
|
||||
networks:
|
||||
- emotion-network
|
||||
|
||||
# Nacos注册中心
|
||||
nacos:
|
||||
image: nacos/nacos-server:v2.2.0
|
||||
container_name: emotion-nacos
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
MODE: standalone
|
||||
SPRING_DATASOURCE_PLATFORM: mysql
|
||||
MYSQL_SERVICE_HOST: mysql
|
||||
MYSQL_SERVICE_DB_NAME: nacos_config
|
||||
MYSQL_SERVICE_PORT: 3306
|
||||
MYSQL_SERVICE_USER: root
|
||||
MYSQL_SERVICE_PASSWORD: 123456
|
||||
MYSQL_SERVICE_DB_PARAM: characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true
|
||||
JVM_XMS: 512m
|
||||
JVM_XMX: 512m
|
||||
JVM_XMN: 256m
|
||||
ports:
|
||||
- "8848:8848"
|
||||
- "9848:9848"
|
||||
volumes:
|
||||
- nacos_data:/home/nacos/data
|
||||
- nacos_logs:/home/nacos/logs
|
||||
depends_on:
|
||||
- mysql
|
||||
networks:
|
||||
- emotion-network
|
||||
|
||||
# 网关服务
|
||||
gateway:
|
||||
build:
|
||||
context: ./backend
|
||||
dockerfile: ./emotion-gateway/Dockerfile
|
||||
container_name: emotion-gateway
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "9000:9000"
|
||||
environment:
|
||||
SPRING_PROFILES_ACTIVE: docker
|
||||
NACOS_SERVER_ADDR: nacos:8848
|
||||
MYSQL_HOST: mysql
|
||||
MYSQL_PORT: 3306
|
||||
REDIS_HOST: redis
|
||||
REDIS_PORT: 6379
|
||||
depends_on:
|
||||
- mysql
|
||||
- redis
|
||||
- nacos
|
||||
networks:
|
||||
- emotion-network
|
||||
|
||||
# AI服务
|
||||
ai-service:
|
||||
build:
|
||||
context: ./backend
|
||||
dockerfile: ./emotion-ai/Dockerfile
|
||||
container_name: emotion-ai
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "9002:9002"
|
||||
environment:
|
||||
SPRING_PROFILES_ACTIVE: docker
|
||||
NACOS_SERVER_ADDR: nacos:8848
|
||||
MYSQL_HOST: mysql
|
||||
MYSQL_PORT: 3306
|
||||
REDIS_HOST: redis
|
||||
REDIS_PORT: 6379
|
||||
depends_on:
|
||||
- mysql
|
||||
- redis
|
||||
- nacos
|
||||
networks:
|
||||
- emotion-network
|
||||
|
||||
# 用户服务
|
||||
user-service:
|
||||
build:
|
||||
context: ./backend
|
||||
dockerfile: ./emotion-user/Dockerfile
|
||||
container_name: emotion-user
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "9001:9001"
|
||||
environment:
|
||||
SPRING_PROFILES_ACTIVE: docker
|
||||
NACOS_SERVER_ADDR: nacos:8848
|
||||
MYSQL_HOST: mysql
|
||||
MYSQL_PORT: 3306
|
||||
REDIS_HOST: redis
|
||||
REDIS_PORT: 6379
|
||||
depends_on:
|
||||
- mysql
|
||||
- redis
|
||||
- nacos
|
||||
networks:
|
||||
- emotion-network
|
||||
|
||||
# 前端应用
|
||||
web:
|
||||
build:
|
||||
context: ./web
|
||||
dockerfile: Dockerfile
|
||||
container_name: emotion-web
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "3000:80"
|
||||
depends_on:
|
||||
- gateway
|
||||
networks:
|
||||
- emotion-network
|
||||
|
||||
# Nginx反向代理
|
||||
nginx:
|
||||
image: nginx:alpine
|
||||
container_name: emotion-nginx
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
volumes:
|
||||
- ./deploy/nginx/nginx.conf:/etc/nginx/nginx.conf
|
||||
- ./deploy/nginx/conf.d:/etc/nginx/conf.d
|
||||
- ./deploy/nginx/ssl:/etc/nginx/ssl
|
||||
- nginx_logs:/var/log/nginx
|
||||
depends_on:
|
||||
- web
|
||||
- gateway
|
||||
networks:
|
||||
- emotion-network
|
||||
|
||||
volumes:
|
||||
mysql_data:
|
||||
redis_data:
|
||||
nacos_data:
|
||||
nacos_logs:
|
||||
nginx_logs:
|
||||
|
||||
networks:
|
||||
emotion-network:
|
||||
driver: bridge
|
||||
@@ -0,0 +1,12 @@
|
||||
# 开发环境配置
|
||||
VITE_APP_ENV=development
|
||||
VITE_APP_TITLE=情绪博物馆(开发环境)
|
||||
|
||||
# 开发环境API配置
|
||||
VITE_API_BASE_URL=/api
|
||||
VITE_API_TARGET=http://localhost:9000
|
||||
VITE_API_TIMEOUT=30000
|
||||
|
||||
# 开发环境特殊配置
|
||||
VITE_DEBUG_MODE=true
|
||||
VITE_MOCK_DATA=false
|
||||
@@ -0,0 +1,13 @@
|
||||
# Docker环境配置
|
||||
VITE_APP_TITLE=情绪博物馆
|
||||
VITE_APP_VERSION=1.0.0
|
||||
VITE_APP_ENV=docker
|
||||
|
||||
# API配置
|
||||
VITE_API_BASE_URL=/api
|
||||
VITE_API_TARGET=http://gateway:9000
|
||||
VITE_API_TIMEOUT=30000
|
||||
|
||||
# 功能开关
|
||||
VITE_DEBUG_MODE=false
|
||||
VITE_MOCK_DATA=false
|
||||
@@ -0,0 +1,12 @@
|
||||
# 生产环境配置
|
||||
VITE_APP_ENV=production
|
||||
VITE_APP_TITLE=情绪博物馆
|
||||
|
||||
# 生产环境API配置
|
||||
VITE_API_BASE_URL=https://api.emotion-museum.com/api
|
||||
VITE_API_TARGET=https://api.emotion-museum.com
|
||||
VITE_API_TIMEOUT=30000
|
||||
|
||||
# 生产环境特殊配置
|
||||
VITE_DEBUG_MODE=false
|
||||
VITE_MOCK_DATA=false
|
||||
@@ -0,0 +1,12 @@
|
||||
# 测试环境配置
|
||||
VITE_APP_ENV=test
|
||||
VITE_APP_TITLE=情绪博物馆(测试环境)
|
||||
|
||||
# 测试环境API配置
|
||||
VITE_API_BASE_URL=https://test-api.emotion-museum.com/api
|
||||
VITE_API_TARGET=https://test-api.emotion-museum.com
|
||||
VITE_API_TIMEOUT=30000
|
||||
|
||||
# 测试环境特殊配置
|
||||
VITE_DEBUG_MODE=true
|
||||
VITE_MOCK_DATA=false
|
||||
@@ -0,0 +1,69 @@
|
||||
# 前端应用Dockerfile - 测试环境版本
|
||||
# 构建阶段
|
||||
FROM node:18-alpine AS builder
|
||||
|
||||
# 构建参数
|
||||
ARG NODE_ENV=test
|
||||
ARG VUE_APP_API_BASE_URL=http://localhost:9000
|
||||
ARG VUE_APP_ENVIRONMENT=test
|
||||
|
||||
# 设置工作目录
|
||||
WORKDIR /app
|
||||
|
||||
# 设置npm镜像源
|
||||
RUN npm config set registry https://registry.npmmirror.com
|
||||
|
||||
# 复制package文件
|
||||
COPY package*.json ./
|
||||
|
||||
# 安装依赖
|
||||
RUN npm ci
|
||||
|
||||
# 复制源代码和配置文件
|
||||
COPY . .
|
||||
COPY config/test.env.js .env.test
|
||||
|
||||
# 设置环境变量
|
||||
ENV NODE_ENV=${NODE_ENV}
|
||||
ENV VUE_APP_API_BASE_URL=${VUE_APP_API_BASE_URL}
|
||||
ENV VUE_APP_ENVIRONMENT=${VUE_APP_ENVIRONMENT}
|
||||
|
||||
# 构建应用
|
||||
RUN npm run build:test || npm run build
|
||||
|
||||
# 生产阶段
|
||||
FROM nginx:alpine
|
||||
|
||||
# 安装必要工具
|
||||
RUN apk add --no-cache curl tzdata && \
|
||||
cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
|
||||
echo "Asia/Shanghai" > /etc/timezone
|
||||
|
||||
# 复制构建产物
|
||||
COPY --from=builder /app/dist /usr/share/nginx/html
|
||||
|
||||
# 复制nginx配置
|
||||
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
||||
|
||||
# 创建nginx用户
|
||||
RUN addgroup -g 101 -S nginx && \
|
||||
adduser -S -D -H -u 101 -h /var/cache/nginx -s /sbin/nologin -G nginx -g nginx nginx
|
||||
|
||||
# 设置权限
|
||||
RUN chown -R nginx:nginx /usr/share/nginx/html && \
|
||||
chown -R nginx:nginx /var/cache/nginx && \
|
||||
chown -R nginx:nginx /var/log/nginx && \
|
||||
chown -R nginx:nginx /etc/nginx/conf.d
|
||||
|
||||
# 创建健康检查页面
|
||||
RUN echo '<!DOCTYPE html><html><head><title>Health Check</title></head><body><h1>OK</h1></body></html>' > /usr/share/nginx/html/health
|
||||
|
||||
# 健康检查
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \
|
||||
CMD curl -f http://localhost:80/health || curl -f http://localhost:80/ || exit 1
|
||||
|
||||
# 暴露端口
|
||||
EXPOSE 80
|
||||
|
||||
# 启动nginx
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
+1
@@ -0,0 +1 @@
|
||||
.analysis-simple[data-v-28c071bd]{min-height:100vh;background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);padding:20px}.analysis-simple .page-header[data-v-28c071bd]{display:flex;justify-content:space-between;align-items:center;background:rgba(255,255,255,.1);padding:20px;border-radius:12px;margin-bottom:20px}.analysis-simple .page-header h1[data-v-28c071bd]{color:#fff;margin:0}.analysis-simple .page-content[data-v-28c071bd]{background:rgba(255,255,255,.95);padding:40px;border-radius:12px;text-align:center}.analysis-simple .page-content .welcome-message h2[data-v-28c071bd]{color:#333;margin-bottom:16px}.analysis-simple .page-content .welcome-message p[data-v-28c071bd]{color:#666;margin-bottom:32px;font-size:16px}.analysis-simple .page-content .welcome-message .test-buttons[data-v-28c071bd]{display:flex;gap:16px;justify-content:center;flex-wrap:wrap}
|
||||
+1
File diff suppressed because one or more lines are too long
+1
@@ -0,0 +1 @@
|
||||
.history-simple[data-v-4baa7231]{min-height:100vh;background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);padding:20px}.history-simple .page-header[data-v-4baa7231]{display:flex;justify-content:space-between;align-items:center;background:rgba(255,255,255,.1);padding:20px;border-radius:12px;margin-bottom:20px}.history-simple .page-header h1[data-v-4baa7231]{color:#fff;margin:0}.history-simple .page-content[data-v-4baa7231]{background:rgba(255,255,255,.95);padding:40px;border-radius:12px;text-align:center}.history-simple .page-content .welcome-message h2[data-v-4baa7231]{color:#333;margin-bottom:16px}.history-simple .page-content .welcome-message p[data-v-4baa7231]{color:#666;margin-bottom:32px;font-size:16px}.history-simple .page-content .welcome-message .test-buttons[data-v-4baa7231]{display:flex;gap:16px;justify-content:center;flex-wrap:wrap}
|
||||
File diff suppressed because one or more lines are too long
+1
@@ -0,0 +1 @@
|
||||
.home-test[data-v-6c328404]{min-height:100vh;background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);padding:40px;text-align:center;color:#fff}h1[data-v-6c328404]{font-size:2.5rem;margin-bottom:20px;text-shadow:2px 2px 4px rgba(0,0,0,.3)}p[data-v-6c328404]{font-size:1.2rem;margin-bottom:30px}.test-buttons[data-v-6c328404]{display:flex;gap:20px;justify-content:center;flex-wrap:wrap;margin-bottom:40px}.test-btn[data-v-6c328404]{padding:12px 24px;font-size:16px;background:rgba(255,255,255,.2);border:2px solid rgba(255,255,255,.3);border-radius:8px;color:#fff;cursor:pointer;transition:all .3s ease}.test-btn[data-v-6c328404]:hover{background:rgba(255,255,255,.3);border-color:#ffffff80;transform:translateY(-2px)}.info[data-v-6c328404]{background:rgba(255,255,255,.1);padding:20px;border-radius:12px;max-width:400px;margin:0 auto}.info p[data-v-6c328404]{margin:10px 0;font-size:1rem}
|
||||
File diff suppressed because one or more lines are too long
+1
@@ -0,0 +1 @@
|
||||
import{_ as d,u as p,b as m,o as v,e as f,f as t,c as o,w as n,g as l}from"./index-bf5be19f.js";const y={class:"analysis-simple"},k={class:"page-header"},b={class:"page-content"},g={class:"welcome-message"},C={class:"test-buttons"},c={__name:"AnalysisSimple",setup(x){const a=p(),_=()=>{a.push("/")},r=()=>{alert("情绪分析页面测试按钮工作正常!")};return(i,s)=>{const e=m("a-button");return v(),f("div",y,[t("div",k,[s[3]||(s[3]=t("h1",null,"情绪分析",-1)),o(e,{onClick:_},{default:n(()=>s[2]||(s[2]=[l("返回首页")])),_:1,__:[2]})]),t("div",b,[t("div",g,[s[7]||(s[7]=t("h2",null,"情绪分析功能",-1)),s[8]||(s[8]=t("p",null,"这里将提供强大的情绪分析功能,帮助您了解自己的情绪状态。",-1)),t("div",C,[o(e,{type:"primary",onClick:r},{default:n(()=>s[4]||(s[4]=[l("测试按钮")])),_:1,__:[4]}),o(e,{onClick:s[0]||(s[0]=u=>i.$router.push("/chat"))},{default:n(()=>s[5]||(s[5]=[l("开始对话")])),_:1,__:[5]}),o(e,{onClick:s[1]||(s[1]=u=>i.$router.push("/history"))},{default:n(()=>s[6]||(s[6]=[l("查看历史")])),_:1,__:[6]})])])])])}}},$=d(c,[["__scopeId","data-v-28c071bd"]]);export{$ as default};
|
||||
+1
File diff suppressed because one or more lines are too long
+1
@@ -0,0 +1 @@
|
||||
import{_ as p,u as d,b as m,o as v,e as f,f as s,c as e,w as n,g as l}from"./index-bf5be19f.js";const y={class:"history-simple"},k={class:"page-header"},b={class:"page-content"},g={class:"welcome-message"},C={class:"test-buttons"},x={__name:"HistorySimple",setup(B){const i=d(),r=()=>{i.push("/")},_=()=>{alert("历史记录页面测试按钮工作正常!")};return(a,t)=>{const o=m("a-button");return v(),f("div",y,[s("div",k,[t[3]||(t[3]=s("h1",null,"对话历史",-1)),e(o,{onClick:r},{default:n(()=>t[2]||(t[2]=[l("返回首页")])),_:1,__:[2]})]),s("div",b,[s("div",g,[t[7]||(t[7]=s("h2",null,"对话历史记录",-1)),t[8]||(t[8]=s("p",null,"这里将显示您的所有对话历史记录。",-1)),s("div",C,[e(o,{type:"primary",onClick:_},{default:n(()=>t[4]||(t[4]=[l("测试按钮")])),_:1,__:[4]}),e(o,{onClick:t[0]||(t[0]=u=>a.$router.push("/chat"))},{default:n(()=>t[5]||(t[5]=[l("开始对话")])),_:1,__:[5]}),e(o,{onClick:t[1]||(t[1]=u=>a.$router.push("/analysis"))},{default:n(()=>t[6]||(t[6]=[l("情绪分析")])),_:1,__:[6]})])])])])}}},c=p(x,[["__scopeId","data-v-4baa7231"]]);export{c as default};
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
import{_ as r,u as i,a as _,k as p,o as d,e as m,f as t,t as b}from"./index-bf5be19f.js";const v={class:"home-test"},T={class:"info"},f={__name:"HomeTest",setup(g){const o=i(),e=_(""),n=()=>{e.value=new Date().toLocaleString()},l=()=>{alert("测试按钮工作正常!Vue应用运行正常!")},a=()=>{o.push("/chat")},u=()=>{o.push("/history")},c=()=>{o.push("/analysis")};return p(()=>{n(),setInterval(n,1e3),console.log("HomeTest页面加载成功")}),(k,s)=>(d(),m("div",v,[s[1]||(s[1]=t("h1",null,"情绪博物馆测试页面",-1)),s[2]||(s[2]=t("p",null,"如果您能看到这个页面,说明Vue应用正在正常工作!",-1)),t("div",{class:"test-buttons"},[t("button",{onClick:l,class:"test-btn"},"测试按钮1"),t("button",{onClick:a,class:"test-btn"},"前往聊天页面"),t("button",{onClick:u,class:"test-btn"},"前往历史页面"),t("button",{onClick:c,class:"test-btn"},"前往分析页面")]),t("div",T,[t("p",null,"当前时间: "+b(e.value),1),s[0]||(s[0]=t("p",null,"页面加载状态: 正常",-1))])]))}},h=r(f,[["__scopeId","data-v-6c328404"]]);export{h as default};
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,78 @@
|
||||
// 测试环境配置
|
||||
module.exports = {
|
||||
NODE_ENV: 'test',
|
||||
|
||||
// API配置
|
||||
VUE_APP_API_BASE_URL: process.env.VUE_APP_API_BASE_URL || 'http://localhost:9000',
|
||||
VUE_APP_GATEWAY_URL: process.env.VUE_APP_GATEWAY_URL || 'http://localhost:9000',
|
||||
|
||||
// 服务端点配置
|
||||
VUE_APP_USER_SERVICE_URL: process.env.VUE_APP_USER_SERVICE_URL || 'http://localhost:9001',
|
||||
VUE_APP_AI_SERVICE_URL: process.env.VUE_APP_AI_SERVICE_URL || 'http://localhost:9002',
|
||||
|
||||
// WebSocket配置
|
||||
VUE_APP_WS_URL: process.env.VUE_APP_WS_URL || 'ws://localhost:9000/ws',
|
||||
|
||||
// 静态资源配置
|
||||
VUE_APP_STATIC_URL: process.env.VUE_APP_STATIC_URL || 'http://localhost:9000/static',
|
||||
VUE_APP_UPLOAD_URL: process.env.VUE_APP_UPLOAD_URL || 'http://localhost:9000/api/upload',
|
||||
|
||||
// 应用配置
|
||||
VUE_APP_TITLE: '情绪博物馆 - 测试环境',
|
||||
VUE_APP_VERSION: '1.0.0',
|
||||
VUE_APP_ENVIRONMENT: 'test',
|
||||
|
||||
// 功能开关
|
||||
VUE_APP_ENABLE_MOCK: 'false',
|
||||
VUE_APP_ENABLE_DEBUG: 'true',
|
||||
VUE_APP_ENABLE_CONSOLE_LOG: 'true',
|
||||
VUE_APP_ENABLE_ERROR_REPORT: 'true',
|
||||
|
||||
// 认证配置
|
||||
VUE_APP_TOKEN_KEY: 'emotion_token',
|
||||
VUE_APP_REFRESH_TOKEN_KEY: 'emotion_refresh_token',
|
||||
VUE_APP_TOKEN_EXPIRE_TIME: 7200, // 2小时
|
||||
|
||||
// 缓存配置
|
||||
VUE_APP_CACHE_PREFIX: 'emotion_test_',
|
||||
VUE_APP_CACHE_EXPIRE_TIME: 3600, // 1小时
|
||||
|
||||
// 请求配置
|
||||
VUE_APP_REQUEST_TIMEOUT: 30000, // 30秒
|
||||
VUE_APP_REQUEST_RETRY_COUNT: 3,
|
||||
VUE_APP_REQUEST_RETRY_DELAY: 1000,
|
||||
|
||||
// 分页配置
|
||||
VUE_APP_PAGE_SIZE: 20,
|
||||
VUE_APP_PAGE_SIZE_OPTIONS: '10,20,50,100',
|
||||
|
||||
// 文件上传配置
|
||||
VUE_APP_UPLOAD_MAX_SIZE: 10485760, // 10MB
|
||||
VUE_APP_UPLOAD_ALLOWED_TYPES: 'image/jpeg,image/png,image/gif,image/webp',
|
||||
|
||||
// AI对话配置
|
||||
VUE_APP_AI_MAX_MESSAGE_LENGTH: 2000,
|
||||
VUE_APP_AI_HISTORY_LIMIT: 20,
|
||||
VUE_APP_AI_TYPING_DELAY: 1000,
|
||||
|
||||
// 主题配置
|
||||
VUE_APP_DEFAULT_THEME: 'light',
|
||||
VUE_APP_THEME_COLOR: '#1890ff',
|
||||
|
||||
// 国际化配置
|
||||
VUE_APP_DEFAULT_LOCALE: 'zh-CN',
|
||||
VUE_APP_FALLBACK_LOCALE: 'en-US',
|
||||
|
||||
// 监控配置
|
||||
VUE_APP_ENABLE_PERFORMANCE_MONITOR: 'true',
|
||||
VUE_APP_ENABLE_ERROR_MONITOR: 'true',
|
||||
VUE_APP_MONITOR_SAMPLE_RATE: 0.1,
|
||||
|
||||
// 安全配置
|
||||
VUE_APP_ENABLE_CSP: 'true',
|
||||
VUE_APP_ENABLE_XSS_PROTECTION: 'true',
|
||||
|
||||
// 开发工具配置
|
||||
VUE_APP_ENABLE_VUE_DEVTOOLS: 'true',
|
||||
VUE_APP_ENABLE_SOURCE_MAP: 'true'
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>情绪博物馆 - AI心理健康助手</title>
|
||||
<meta name="description" content="情绪博物馆 - 您的专属AI心理健康助手,提供情绪分析、心理支持和个性化建议" />
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
#app {
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.loading {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
color: white;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.loading::after {
|
||||
content: '';
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border: 2px solid transparent;
|
||||
border-top: 2px solid white;
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
</style>
|
||||
<script type="module" crossorigin src="/assets/js/index-bf5be19f.js"></script>
|
||||
<link rel="stylesheet" href="/assets/css/index-4213a94d.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app">
|
||||
<div class="loading">加载中...</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,64 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name localhost;
|
||||
root /usr/share/nginx/html;
|
||||
index index.html index.htm;
|
||||
|
||||
# Gzip压缩
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
gzip_min_length 1024;
|
||||
gzip_comp_level 6;
|
||||
gzip_types
|
||||
text/plain
|
||||
text/css
|
||||
text/xml
|
||||
text/javascript
|
||||
application/json
|
||||
application/javascript
|
||||
application/xml+rss
|
||||
application/atom+xml
|
||||
image/svg+xml;
|
||||
|
||||
# 静态资源缓存
|
||||
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
|
||||
expires 1y;
|
||||
add_header Cache-Control "public, immutable";
|
||||
add_header Vary "Accept-Encoding";
|
||||
try_files $uri =404;
|
||||
}
|
||||
|
||||
# HTML文件不缓存
|
||||
location ~* \.(html|htm)$ {
|
||||
expires -1;
|
||||
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
||||
add_header Pragma "no-cache";
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
||||
# SPA路由支持
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
|
||||
# 安全头
|
||||
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;
|
||||
}
|
||||
|
||||
# 健康检查
|
||||
location /health {
|
||||
access_log off;
|
||||
return 200 "healthy\n";
|
||||
add_header Content-Type text/plain;
|
||||
}
|
||||
|
||||
# 错误页面
|
||||
error_page 404 /index.html;
|
||||
error_page 500 502 503 504 /50x.html;
|
||||
|
||||
location = /50x.html {
|
||||
root /usr/share/nginx/html;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,309 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 情绪博物馆数据库初始化脚本
|
||||
# 作者: EmotionMuseum Team
|
||||
# 版本: 1.0.0
|
||||
# 日期: 2025-07-13
|
||||
# 说明: 初始化MySQL数据库和Nacos配置数据库
|
||||
|
||||
set -e
|
||||
|
||||
# 颜色定义
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
# 日志函数
|
||||
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_step() {
|
||||
echo -e "${BLUE}[STEP]${NC} $1"
|
||||
}
|
||||
|
||||
# 配置变量
|
||||
MYSQL_ROOT_PASSWORD="123456"
|
||||
MYSQL_HOST="localhost"
|
||||
MYSQL_PORT="3306"
|
||||
EMOTION_DB_NAME="emotion_museum"
|
||||
NACOS_DB_NAME="nacos_config"
|
||||
EMOTION_USER="emotion"
|
||||
EMOTION_PASSWORD="emotion123"
|
||||
|
||||
# 检查Docker是否运行
|
||||
check_docker() {
|
||||
log_step "检查Docker服务..."
|
||||
|
||||
if ! command -v docker &> /dev/null; then
|
||||
log_error "Docker未安装,请先运行 ./install-environment.sh"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! docker info &> /dev/null; then
|
||||
log_error "Docker服务未启动,请启动Docker服务"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_info "Docker服务正常"
|
||||
}
|
||||
|
||||
# 启动MySQL容器
|
||||
start_mysql_container() {
|
||||
log_step "启动MySQL容器..."
|
||||
|
||||
# 检查是否已有MySQL容器运行
|
||||
if docker ps -a | grep -q "emotion-mysql"; then
|
||||
log_info "检测到已存在的MySQL容器"
|
||||
if docker ps | grep -q "emotion-mysql"; then
|
||||
log_info "MySQL容器已在运行"
|
||||
return
|
||||
else
|
||||
log_info "启动已存在的MySQL容器"
|
||||
docker start emotion-mysql
|
||||
sleep 10
|
||||
return
|
||||
fi
|
||||
fi
|
||||
|
||||
# 创建数据目录
|
||||
mkdir -p ./data/mysql
|
||||
|
||||
# 启动新的MySQL容器
|
||||
log_info "创建新的MySQL容器..."
|
||||
docker run -d \
|
||||
--name emotion-mysql \
|
||||
--restart unless-stopped \
|
||||
-e MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD \
|
||||
-e TZ=Asia/Shanghai \
|
||||
-p $MYSQL_PORT:3306 \
|
||||
-v $(pwd)/data/mysql:/var/lib/mysql \
|
||||
mysql:8.0 \
|
||||
--default-authentication-plugin=mysql_native_password \
|
||||
--character-set-server=utf8mb4 \
|
||||
--collation-server=utf8mb4_unicode_ci \
|
||||
--default-time-zone='+8:00'
|
||||
|
||||
log_info "等待MySQL容器启动..."
|
||||
sleep 30
|
||||
|
||||
# 等待MySQL服务就绪
|
||||
local retry_count=0
|
||||
local max_retries=30
|
||||
|
||||
while [ $retry_count -lt $max_retries ]; do
|
||||
if docker exec emotion-mysql mysqladmin ping -h localhost -u root -p$MYSQL_ROOT_PASSWORD &> /dev/null; then
|
||||
log_info "MySQL服务已就绪"
|
||||
break
|
||||
fi
|
||||
|
||||
retry_count=$((retry_count + 1))
|
||||
log_info "等待MySQL服务就绪... ($retry_count/$max_retries)"
|
||||
sleep 2
|
||||
done
|
||||
|
||||
if [ $retry_count -eq $max_retries ]; then
|
||||
log_error "MySQL服务启动超时"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# 创建数据库和用户
|
||||
create_databases() {
|
||||
log_step "创建数据库和用户..."
|
||||
|
||||
# 创建情绪博物馆数据库
|
||||
log_info "创建情绪博物馆数据库..."
|
||||
docker exec emotion-mysql mysql -u root -p$MYSQL_ROOT_PASSWORD -e "
|
||||
CREATE DATABASE IF NOT EXISTS $EMOTION_DB_NAME CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
CREATE USER IF NOT EXISTS '$EMOTION_USER'@'%' IDENTIFIED BY '$EMOTION_PASSWORD';
|
||||
GRANT ALL PRIVILEGES ON $EMOTION_DB_NAME.* TO '$EMOTION_USER'@'%';
|
||||
FLUSH PRIVILEGES;
|
||||
"
|
||||
|
||||
# 创建Nacos配置数据库
|
||||
log_info "创建Nacos配置数据库..."
|
||||
docker exec emotion-mysql mysql -u root -p$MYSQL_ROOT_PASSWORD -e "
|
||||
CREATE DATABASE IF NOT EXISTS $NACOS_DB_NAME CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
GRANT ALL PRIVILEGES ON $NACOS_DB_NAME.* TO '$EMOTION_USER'@'%';
|
||||
FLUSH PRIVILEGES;
|
||||
"
|
||||
|
||||
log_info "数据库创建完成"
|
||||
}
|
||||
|
||||
# 初始化情绪博物馆数据库表结构
|
||||
init_emotion_database() {
|
||||
log_step "初始化情绪博物馆数据库表结构..."
|
||||
|
||||
if [ ! -f "./database/mysql_emotion_museum_final.sql" ]; then
|
||||
log_error "数据库初始化脚本不存在: ./database/mysql_emotion_museum_final.sql"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_info "执行数据库初始化脚本..."
|
||||
docker exec -i emotion-mysql mysql -u root -p$MYSQL_ROOT_PASSWORD $EMOTION_DB_NAME < ./database/mysql_emotion_museum_final.sql
|
||||
|
||||
log_info "情绪博物馆数据库初始化完成"
|
||||
}
|
||||
|
||||
# 初始化Nacos配置数据库
|
||||
init_nacos_database() {
|
||||
log_step "初始化Nacos配置数据库..."
|
||||
|
||||
# 下载Nacos数据库初始化脚本
|
||||
local nacos_sql_url="https://raw.githubusercontent.com/alibaba/nacos/2.2.0/distribution/conf/nacos-mysql.sql"
|
||||
local nacos_sql_file="./database/nacos-mysql.sql"
|
||||
|
||||
if [ ! -f "$nacos_sql_file" ]; then
|
||||
log_info "下载Nacos数据库初始化脚本..."
|
||||
mkdir -p ./database
|
||||
curl -fsSL $nacos_sql_url -o $nacos_sql_file
|
||||
fi
|
||||
|
||||
log_info "执行Nacos数据库初始化脚本..."
|
||||
docker exec -i emotion-mysql mysql -u root -p$MYSQL_ROOT_PASSWORD $NACOS_DB_NAME < $nacos_sql_file
|
||||
|
||||
log_info "Nacos配置数据库初始化完成"
|
||||
}
|
||||
|
||||
# 验证数据库初始化
|
||||
verify_database() {
|
||||
log_step "验证数据库初始化..."
|
||||
|
||||
echo ""
|
||||
echo "=== 数据库验证结果 ==="
|
||||
|
||||
# 验证情绪博物馆数据库
|
||||
log_info "验证情绪博物馆数据库..."
|
||||
local emotion_tables=$(docker exec emotion-mysql mysql -u root -p$MYSQL_ROOT_PASSWORD -e "USE $EMOTION_DB_NAME; SHOW TABLES;" | wc -l)
|
||||
if [ $emotion_tables -gt 1 ]; then
|
||||
log_info "✅ 情绪博物馆数据库表数量: $((emotion_tables - 1))"
|
||||
else
|
||||
log_error "❌ 情绪博物馆数据库初始化失败"
|
||||
fi
|
||||
|
||||
# 验证Nacos配置数据库
|
||||
log_info "验证Nacos配置数据库..."
|
||||
local nacos_tables=$(docker exec emotion-mysql mysql -u root -p$MYSQL_ROOT_PASSWORD -e "USE $NACOS_DB_NAME; SHOW TABLES;" | wc -l)
|
||||
if [ $nacos_tables -gt 1 ]; then
|
||||
log_info "✅ Nacos配置数据库表数量: $((nacos_tables - 1))"
|
||||
else
|
||||
log_error "❌ Nacos配置数据库初始化失败"
|
||||
fi
|
||||
|
||||
# 验证用户权限
|
||||
log_info "验证数据库用户权限..."
|
||||
if docker exec emotion-mysql mysql -u $EMOTION_USER -p$EMOTION_PASSWORD -e "USE $EMOTION_DB_NAME; SELECT 1;" &> /dev/null; then
|
||||
log_info "✅ 情绪博物馆数据库用户权限正常"
|
||||
else
|
||||
log_error "❌ 情绪博物馆数据库用户权限异常"
|
||||
fi
|
||||
|
||||
if docker exec emotion-mysql mysql -u $EMOTION_USER -p$EMOTION_PASSWORD -e "USE $NACOS_DB_NAME; SELECT 1;" &> /dev/null; then
|
||||
log_info "✅ Nacos数据库用户权限正常"
|
||||
else
|
||||
log_error "❌ Nacos数据库用户权限异常"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
log_info "数据库验证完成"
|
||||
}
|
||||
|
||||
# 显示数据库连接信息
|
||||
show_database_info() {
|
||||
log_step "数据库连接信息"
|
||||
|
||||
echo ""
|
||||
echo "🗄️ 数据库连接信息:"
|
||||
echo " MySQL主机: $MYSQL_HOST:$MYSQL_PORT"
|
||||
echo " Root密码: $MYSQL_ROOT_PASSWORD"
|
||||
echo " 情绪博物馆数据库: $EMOTION_DB_NAME"
|
||||
echo " Nacos配置数据库: $NACOS_DB_NAME"
|
||||
echo " 应用用户: $EMOTION_USER"
|
||||
echo " 应用密码: $EMOTION_PASSWORD"
|
||||
echo ""
|
||||
echo "🔧 管理命令:"
|
||||
echo " 连接MySQL: docker exec -it emotion-mysql mysql -u root -p$MYSQL_ROOT_PASSWORD"
|
||||
echo " 查看日志: docker logs emotion-mysql"
|
||||
echo " 停止容器: docker stop emotion-mysql"
|
||||
echo " 启动容器: docker start emotion-mysql"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# 清理数据库(危险操作)
|
||||
clean_database() {
|
||||
log_warn "⚠️ 这将删除所有数据库数据,此操作不可逆!"
|
||||
read -p "确认删除所有数据库数据? (输入 'YES' 确认): " -r
|
||||
|
||||
if [ "$REPLY" = "YES" ]; then
|
||||
log_step "清理数据库..."
|
||||
|
||||
# 停止并删除MySQL容器
|
||||
docker stop emotion-mysql 2>/dev/null || true
|
||||
docker rm emotion-mysql 2>/dev/null || true
|
||||
|
||||
# 删除数据目录
|
||||
sudo rm -rf ./data/mysql
|
||||
|
||||
log_info "数据库清理完成"
|
||||
else
|
||||
log_info "清理操作已取消"
|
||||
fi
|
||||
}
|
||||
|
||||
# 主函数
|
||||
main() {
|
||||
echo "🗄️ 开始初始化情绪博物馆数据库..."
|
||||
echo ""
|
||||
|
||||
check_docker
|
||||
start_mysql_container
|
||||
create_databases
|
||||
init_emotion_database
|
||||
init_nacos_database
|
||||
verify_database
|
||||
show_database_info
|
||||
|
||||
echo ""
|
||||
log_info "🎉 数据库初始化完成!"
|
||||
}
|
||||
|
||||
# 处理命令行参数
|
||||
case "${1:-}" in
|
||||
"start")
|
||||
check_docker
|
||||
start_mysql_container
|
||||
show_database_info
|
||||
;;
|
||||
"init")
|
||||
check_docker
|
||||
start_mysql_container
|
||||
create_databases
|
||||
init_emotion_database
|
||||
init_nacos_database
|
||||
verify_database
|
||||
;;
|
||||
"verify")
|
||||
verify_database
|
||||
;;
|
||||
"clean")
|
||||
clean_database
|
||||
;;
|
||||
"info")
|
||||
show_database_info
|
||||
;;
|
||||
*)
|
||||
main
|
||||
;;
|
||||
esac
|
||||
@@ -0,0 +1,382 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 情绪博物馆环境安装脚本
|
||||
# 作者: EmotionMuseum Team
|
||||
# 版本: 1.0.0
|
||||
# 日期: 2025-07-13
|
||||
# 说明: 安装部署所需的基础环境
|
||||
|
||||
set -e
|
||||
|
||||
# 颜色定义
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
# 日志函数
|
||||
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_step() {
|
||||
echo -e "${BLUE}[STEP]${NC} $1"
|
||||
}
|
||||
|
||||
# 检测操作系统
|
||||
detect_os() {
|
||||
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
|
||||
if [ -f /etc/redhat-release ]; then
|
||||
OS="centos"
|
||||
PKG_MANAGER="yum"
|
||||
elif [ -f /etc/debian_version ]; then
|
||||
OS="ubuntu"
|
||||
PKG_MANAGER="apt"
|
||||
else
|
||||
OS="linux"
|
||||
PKG_MANAGER="unknown"
|
||||
fi
|
||||
elif [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
OS="macos"
|
||||
PKG_MANAGER="brew"
|
||||
else
|
||||
log_error "不支持的操作系统: $OSTYPE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_info "检测到操作系统: $OS"
|
||||
}
|
||||
|
||||
# 更新系统包管理器
|
||||
update_package_manager() {
|
||||
log_step "更新系统包管理器..."
|
||||
|
||||
case $PKG_MANAGER in
|
||||
"yum")
|
||||
sudo yum update -y
|
||||
sudo yum install -y wget curl git unzip
|
||||
;;
|
||||
"apt")
|
||||
sudo apt update
|
||||
sudo apt upgrade -y
|
||||
sudo apt install -y wget curl git unzip software-properties-common
|
||||
;;
|
||||
"brew")
|
||||
if ! command -v brew &> /dev/null; then
|
||||
log_info "安装Homebrew..."
|
||||
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
||||
fi
|
||||
brew update
|
||||
;;
|
||||
*)
|
||||
log_error "不支持的包管理器: $PKG_MANAGER"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
log_info "系统包管理器更新完成"
|
||||
}
|
||||
|
||||
# 安装Java 17
|
||||
install_java() {
|
||||
log_step "安装Java 17..."
|
||||
|
||||
if command -v java &> /dev/null; then
|
||||
JAVA_VERSION=$(java -version 2>&1 | head -n1 | cut -d'"' -f2 | cut -d'.' -f1)
|
||||
if [ "$JAVA_VERSION" = "17" ]; then
|
||||
log_info "Java 17已安装"
|
||||
return
|
||||
else
|
||||
log_warn "检测到Java版本: $JAVA_VERSION,将安装Java 17"
|
||||
fi
|
||||
fi
|
||||
|
||||
case $PKG_MANAGER in
|
||||
"yum")
|
||||
sudo yum install -y java-17-openjdk java-17-openjdk-devel
|
||||
;;
|
||||
"apt")
|
||||
sudo apt install -y openjdk-17-jdk openjdk-17-jre
|
||||
;;
|
||||
"brew")
|
||||
brew install openjdk@17
|
||||
echo 'export PATH="/opt/homebrew/opt/openjdk@17/bin:$PATH"' >> ~/.zshrc
|
||||
;;
|
||||
esac
|
||||
|
||||
# 设置JAVA_HOME
|
||||
JAVA_HOME_PATH=$(dirname $(dirname $(readlink -f $(which java))))
|
||||
echo "export JAVA_HOME=$JAVA_HOME_PATH" >> ~/.bashrc
|
||||
echo "export PATH=\$JAVA_HOME/bin:\$PATH" >> ~/.bashrc
|
||||
|
||||
if [ "$OS" = "macos" ]; then
|
||||
echo "export JAVA_HOME=$JAVA_HOME_PATH" >> ~/.zshrc
|
||||
echo "export PATH=\$JAVA_HOME/bin:\$PATH" >> ~/.zshrc
|
||||
fi
|
||||
|
||||
log_info "Java 17安装完成"
|
||||
}
|
||||
|
||||
# 安装Maven
|
||||
install_maven() {
|
||||
log_step "安装Maven..."
|
||||
|
||||
if command -v mvn &> /dev/null; then
|
||||
MVN_VERSION=$(mvn -version | head -n1 | cut -d' ' -f3)
|
||||
log_info "Maven已安装,版本: $MVN_VERSION"
|
||||
return
|
||||
fi
|
||||
|
||||
MAVEN_VERSION="3.9.6"
|
||||
MAVEN_URL="https://archive.apache.org/dist/maven/maven-3/${MAVEN_VERSION}/binaries/apache-maven-${MAVEN_VERSION}-bin.tar.gz"
|
||||
|
||||
cd /tmp
|
||||
wget $MAVEN_URL
|
||||
sudo tar -xzf apache-maven-${MAVEN_VERSION}-bin.tar.gz -C /opt/
|
||||
sudo ln -sf /opt/apache-maven-${MAVEN_VERSION} /opt/maven
|
||||
|
||||
echo "export MAVEN_HOME=/opt/maven" >> ~/.bashrc
|
||||
echo "export PATH=\$MAVEN_HOME/bin:\$PATH" >> ~/.bashrc
|
||||
|
||||
if [ "$OS" = "macos" ]; then
|
||||
echo "export MAVEN_HOME=/opt/maven" >> ~/.zshrc
|
||||
echo "export PATH=\$MAVEN_HOME/bin:\$PATH" >> ~/.zshrc
|
||||
fi
|
||||
|
||||
log_info "Maven安装完成"
|
||||
}
|
||||
|
||||
# 安装Node.js和npm
|
||||
install_nodejs() {
|
||||
log_step "安装Node.js和npm..."
|
||||
|
||||
if command -v node &> /dev/null; then
|
||||
NODE_VERSION=$(node -v)
|
||||
log_info "Node.js已安装,版本: $NODE_VERSION"
|
||||
if command -v npm &> /dev/null; then
|
||||
NPM_VERSION=$(npm -v)
|
||||
log_info "npm已安装,版本: $NPM_VERSION"
|
||||
return
|
||||
fi
|
||||
fi
|
||||
|
||||
# 使用NodeSource安装最新LTS版本
|
||||
case $PKG_MANAGER in
|
||||
"yum")
|
||||
curl -fsSL https://rpm.nodesource.com/setup_lts.x | sudo bash -
|
||||
sudo yum install -y nodejs
|
||||
;;
|
||||
"apt")
|
||||
curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -
|
||||
sudo apt-get install -y nodejs
|
||||
;;
|
||||
"brew")
|
||||
brew install node
|
||||
;;
|
||||
esac
|
||||
|
||||
# 配置npm镜像源
|
||||
npm config set registry https://registry.npmmirror.com
|
||||
|
||||
log_info "Node.js和npm安装完成"
|
||||
}
|
||||
|
||||
# 安装Docker
|
||||
install_docker() {
|
||||
log_step "安装Docker..."
|
||||
|
||||
if command -v docker &> /dev/null; then
|
||||
DOCKER_VERSION=$(docker --version | cut -d' ' -f3 | cut -d',' -f1)
|
||||
log_info "Docker已安装,版本: $DOCKER_VERSION"
|
||||
else
|
||||
case $PKG_MANAGER in
|
||||
"yum")
|
||||
sudo yum install -y yum-utils
|
||||
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
|
||||
sudo yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
|
||||
;;
|
||||
"apt")
|
||||
sudo apt-get remove docker docker-engine docker.io containerd runc || true
|
||||
sudo apt-get install -y ca-certificates curl gnupg lsb-release
|
||||
sudo mkdir -p /etc/apt/keyrings
|
||||
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
|
||||
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
|
||||
;;
|
||||
"brew")
|
||||
log_info "请手动安装Docker Desktop for Mac"
|
||||
log_info "下载地址: https://www.docker.com/products/docker-desktop"
|
||||
return
|
||||
;;
|
||||
esac
|
||||
|
||||
log_info "Docker安装完成"
|
||||
fi
|
||||
|
||||
# 启动Docker服务
|
||||
if [ "$OS" != "macos" ]; then
|
||||
sudo systemctl start docker
|
||||
sudo systemctl enable docker
|
||||
|
||||
# 将当前用户添加到docker组
|
||||
sudo usermod -aG docker $USER
|
||||
log_warn "请重新登录以使docker组权限生效"
|
||||
fi
|
||||
}
|
||||
|
||||
# 安装Docker Compose
|
||||
install_docker_compose() {
|
||||
log_step "安装Docker Compose..."
|
||||
|
||||
if command -v docker-compose &> /dev/null; then
|
||||
COMPOSE_VERSION=$(docker-compose --version | cut -d' ' -f3 | cut -d',' -f1)
|
||||
log_info "Docker Compose已安装,版本: $COMPOSE_VERSION"
|
||||
return
|
||||
fi
|
||||
|
||||
# 安装最新版本的Docker Compose
|
||||
COMPOSE_VERSION=$(curl -s https://api.github.com/repos/docker/compose/releases/latest | grep 'tag_name' | cut -d'"' -f4)
|
||||
sudo curl -L "https://github.com/docker/compose/releases/download/${COMPOSE_VERSION}/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
|
||||
sudo chmod +x /usr/local/bin/docker-compose
|
||||
|
||||
log_info "Docker Compose安装完成"
|
||||
}
|
||||
|
||||
# 配置系统优化
|
||||
configure_system() {
|
||||
log_step "配置系统优化..."
|
||||
|
||||
if [ "$OS" != "macos" ]; then
|
||||
# 增加文件描述符限制
|
||||
echo "* soft nofile 65536" | sudo tee -a /etc/security/limits.conf
|
||||
echo "* hard nofile 65536" | sudo tee -a /etc/security/limits.conf
|
||||
|
||||
# 配置内核参数
|
||||
echo "vm.max_map_count=262144" | sudo tee -a /etc/sysctl.conf
|
||||
echo "net.core.somaxconn=65535" | sudo tee -a /etc/sysctl.conf
|
||||
|
||||
sudo sysctl -p
|
||||
fi
|
||||
|
||||
log_info "系统优化配置完成"
|
||||
}
|
||||
|
||||
# 验证安装
|
||||
verify_installation() {
|
||||
log_step "验证安装结果..."
|
||||
|
||||
echo ""
|
||||
echo "=== 环境验证结果 ==="
|
||||
|
||||
# 验证Java
|
||||
if command -v java &> /dev/null; then
|
||||
JAVA_VERSION=$(java -version 2>&1 | head -n1)
|
||||
log_info "✅ Java: $JAVA_VERSION"
|
||||
else
|
||||
log_error "❌ Java未安装"
|
||||
fi
|
||||
|
||||
# 验证Maven
|
||||
if command -v mvn &> /dev/null; then
|
||||
MVN_VERSION=$(mvn -version | head -n1)
|
||||
log_info "✅ Maven: $MVN_VERSION"
|
||||
else
|
||||
log_error "❌ Maven未安装"
|
||||
fi
|
||||
|
||||
# 验证Node.js
|
||||
if command -v node &> /dev/null; then
|
||||
NODE_VERSION=$(node -v)
|
||||
log_info "✅ Node.js: $NODE_VERSION"
|
||||
else
|
||||
log_error "❌ Node.js未安装"
|
||||
fi
|
||||
|
||||
# 验证npm
|
||||
if command -v npm &> /dev/null; then
|
||||
NPM_VERSION=$(npm -v)
|
||||
log_info "✅ npm: $NPM_VERSION"
|
||||
else
|
||||
log_error "❌ npm未安装"
|
||||
fi
|
||||
|
||||
# 验证Docker
|
||||
if command -v docker &> /dev/null; then
|
||||
DOCKER_VERSION=$(docker --version)
|
||||
log_info "✅ Docker: $DOCKER_VERSION"
|
||||
else
|
||||
log_error "❌ Docker未安装"
|
||||
fi
|
||||
|
||||
# 验证Docker Compose
|
||||
if command -v docker-compose &> /dev/null; then
|
||||
COMPOSE_VERSION=$(docker-compose --version)
|
||||
log_info "✅ Docker Compose: $COMPOSE_VERSION"
|
||||
else
|
||||
log_error "❌ Docker Compose未安装"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
log_info "环境验证完成"
|
||||
}
|
||||
|
||||
# 主函数
|
||||
main() {
|
||||
echo "🚀 开始安装情绪博物馆部署环境..."
|
||||
echo ""
|
||||
|
||||
detect_os
|
||||
update_package_manager
|
||||
install_java
|
||||
install_maven
|
||||
install_nodejs
|
||||
install_docker
|
||||
install_docker_compose
|
||||
configure_system
|
||||
verify_installation
|
||||
|
||||
echo ""
|
||||
log_info "🎉 环境安装完成!"
|
||||
log_warn "请重新登录或执行 'source ~/.bashrc' 以使环境变量生效"
|
||||
|
||||
if [ "$OS" = "macos" ]; then
|
||||
log_warn "macOS用户请执行 'source ~/.zshrc' 以使环境变量生效"
|
||||
fi
|
||||
}
|
||||
|
||||
# 处理命令行参数
|
||||
case "${1:-}" in
|
||||
"java")
|
||||
detect_os
|
||||
install_java
|
||||
;;
|
||||
"maven")
|
||||
detect_os
|
||||
install_maven
|
||||
;;
|
||||
"node")
|
||||
detect_os
|
||||
install_nodejs
|
||||
;;
|
||||
"docker")
|
||||
detect_os
|
||||
install_docker
|
||||
install_docker_compose
|
||||
;;
|
||||
"verify")
|
||||
verify_installation
|
||||
;;
|
||||
*)
|
||||
main
|
||||
;;
|
||||
esac
|
||||
+412
@@ -0,0 +1,412 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 情绪博物馆管理脚本
|
||||
# 提供服务管理、监控、备份等功能
|
||||
|
||||
set -e
|
||||
|
||||
# 颜色定义
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
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_step() {
|
||||
echo -e "${BLUE}[STEP]${NC} $1"
|
||||
}
|
||||
|
||||
# 显示帮助信息
|
||||
show_help() {
|
||||
echo "情绪博物馆管理脚本"
|
||||
echo ""
|
||||
echo "用法: $0 [命令] [选项]"
|
||||
echo ""
|
||||
echo "命令:"
|
||||
echo " start 启动所有服务"
|
||||
echo " stop 停止所有服务"
|
||||
echo " restart 重启所有服务"
|
||||
echo " status 查看服务状态"
|
||||
echo " logs 查看服务日志"
|
||||
echo " backup 备份数据"
|
||||
echo " restore 恢复数据"
|
||||
echo " update 更新服务"
|
||||
echo " clean 清理资源"
|
||||
echo " monitor 监控服务"
|
||||
echo " health 健康检查"
|
||||
echo ""
|
||||
echo "选项:"
|
||||
echo " -f, --follow 跟踪日志输出"
|
||||
echo " -s, --service 指定服务名称"
|
||||
echo " -h, --help 显示帮助信息"
|
||||
echo ""
|
||||
echo "示例:"
|
||||
echo " $0 start # 启动所有服务"
|
||||
echo " $0 logs -f # 跟踪所有服务日志"
|
||||
echo " $0 logs -s gateway # 查看网关服务日志"
|
||||
echo " $0 restart -s ai-service # 重启AI服务"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# 启动服务
|
||||
start_services() {
|
||||
log_step "启动服务..."
|
||||
|
||||
if [ -f "docker-compose.prod.yml" ]; then
|
||||
docker-compose -f docker-compose.prod.yml up -d
|
||||
else
|
||||
docker-compose up -d
|
||||
fi
|
||||
|
||||
log_info "服务启动完成"
|
||||
sleep 5
|
||||
show_status
|
||||
}
|
||||
|
||||
# 停止服务
|
||||
stop_services() {
|
||||
log_step "停止服务..."
|
||||
|
||||
if [ -f "docker-compose.prod.yml" ]; then
|
||||
docker-compose -f docker-compose.prod.yml down
|
||||
else
|
||||
docker-compose down
|
||||
fi
|
||||
|
||||
log_info "服务停止完成"
|
||||
}
|
||||
|
||||
# 重启服务
|
||||
restart_services() {
|
||||
local service_name=${1:-}
|
||||
|
||||
if [ -n "$service_name" ]; then
|
||||
log_step "重启服务: $service_name"
|
||||
docker-compose restart "$service_name"
|
||||
else
|
||||
log_step "重启所有服务..."
|
||||
stop_services
|
||||
sleep 3
|
||||
start_services
|
||||
fi
|
||||
}
|
||||
|
||||
# 查看服务状态
|
||||
show_status() {
|
||||
log_step "服务状态:"
|
||||
echo ""
|
||||
docker-compose ps
|
||||
echo ""
|
||||
|
||||
# 显示资源使用情况
|
||||
log_step "资源使用情况:"
|
||||
docker stats --no-stream --format "table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}\t{{.BlockIO}}"
|
||||
}
|
||||
|
||||
# 查看日志
|
||||
show_logs() {
|
||||
local follow_flag=""
|
||||
local service_name=""
|
||||
|
||||
# 解析参数
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
-f|--follow)
|
||||
follow_flag="-f"
|
||||
shift
|
||||
;;
|
||||
-s|--service)
|
||||
service_name="$2"
|
||||
shift 2
|
||||
;;
|
||||
*)
|
||||
service_name="$1"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -n "$service_name" ]; then
|
||||
log_info "查看服务日志: $service_name"
|
||||
docker-compose logs $follow_flag "$service_name"
|
||||
else
|
||||
log_info "查看所有服务日志"
|
||||
docker-compose logs $follow_flag
|
||||
fi
|
||||
}
|
||||
|
||||
# 备份数据
|
||||
backup_data() {
|
||||
local backup_dir="backups/$(date +%Y%m%d_%H%M%S)"
|
||||
|
||||
log_step "开始数据备份..."
|
||||
mkdir -p "$backup_dir"
|
||||
|
||||
# 备份MySQL数据
|
||||
log_info "备份MySQL数据..."
|
||||
docker-compose exec -T mysql mysqldump -u root -p123456 --all-databases > "$backup_dir/mysql_backup.sql"
|
||||
|
||||
# 备份Redis数据
|
||||
log_info "备份Redis数据..."
|
||||
docker-compose exec -T redis redis-cli BGSAVE
|
||||
docker cp $(docker-compose ps -q redis):/data/dump.rdb "$backup_dir/redis_backup.rdb"
|
||||
|
||||
# 备份配置文件
|
||||
log_info "备份配置文件..."
|
||||
cp -r deploy "$backup_dir/"
|
||||
cp docker-compose*.yml "$backup_dir/"
|
||||
cp .env "$backup_dir/" 2>/dev/null || true
|
||||
|
||||
# 压缩备份
|
||||
tar -czf "$backup_dir.tar.gz" -C backups "$(basename $backup_dir)"
|
||||
rm -rf "$backup_dir"
|
||||
|
||||
log_info "备份完成: $backup_dir.tar.gz"
|
||||
}
|
||||
|
||||
# 恢复数据
|
||||
restore_data() {
|
||||
local backup_file="$1"
|
||||
|
||||
if [ -z "$backup_file" ]; then
|
||||
log_error "请指定备份文件"
|
||||
echo "用法: $0 restore <backup_file.tar.gz>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$backup_file" ]; then
|
||||
log_error "备份文件不存在: $backup_file"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_step "开始数据恢复..."
|
||||
log_warn "此操作将覆盖现有数据,请确认后继续"
|
||||
read -p "是否继续? (y/N): " -n 1 -r
|
||||
echo
|
||||
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
log_info "恢复操作已取消"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# 解压备份文件
|
||||
local restore_dir="restore_$(date +%Y%m%d_%H%M%S)"
|
||||
mkdir -p "$restore_dir"
|
||||
tar -xzf "$backup_file" -C "$restore_dir"
|
||||
|
||||
# 恢复MySQL数据
|
||||
log_info "恢复MySQL数据..."
|
||||
docker-compose exec -T mysql mysql -u root -p123456 < "$restore_dir"/*/mysql_backup.sql
|
||||
|
||||
# 恢复Redis数据
|
||||
log_info "恢复Redis数据..."
|
||||
docker-compose stop redis
|
||||
docker cp "$restore_dir"/*/redis_backup.rdb $(docker-compose ps -q redis):/data/dump.rdb
|
||||
docker-compose start redis
|
||||
|
||||
# 清理临时文件
|
||||
rm -rf "$restore_dir"
|
||||
|
||||
log_info "数据恢复完成"
|
||||
}
|
||||
|
||||
# 更新服务
|
||||
update_services() {
|
||||
log_step "更新服务..."
|
||||
|
||||
# 拉取最新代码
|
||||
if [ -d ".git" ]; then
|
||||
log_info "拉取最新代码..."
|
||||
git pull
|
||||
fi
|
||||
|
||||
# 重新构建镜像
|
||||
log_info "重新构建镜像..."
|
||||
docker-compose build --no-cache
|
||||
|
||||
# 重启服务
|
||||
log_info "重启服务..."
|
||||
restart_services
|
||||
|
||||
log_info "服务更新完成"
|
||||
}
|
||||
|
||||
# 清理资源
|
||||
clean_resources() {
|
||||
log_step "清理Docker资源..."
|
||||
|
||||
log_warn "此操作将清理未使用的Docker资源"
|
||||
read -p "是否继续? (y/N): " -n 1 -r
|
||||
echo
|
||||
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
# 清理未使用的镜像
|
||||
docker image prune -f
|
||||
|
||||
# 清理未使用的容器
|
||||
docker container prune -f
|
||||
|
||||
# 清理未使用的网络
|
||||
docker network prune -f
|
||||
|
||||
# 清理未使用的卷(谨慎使用)
|
||||
# docker volume prune -f
|
||||
|
||||
log_info "资源清理完成"
|
||||
else
|
||||
log_info "清理操作已取消"
|
||||
fi
|
||||
}
|
||||
|
||||
# 监控服务
|
||||
monitor_services() {
|
||||
log_step "服务监控面板"
|
||||
echo ""
|
||||
|
||||
while true; do
|
||||
clear
|
||||
echo "=== 情绪博物馆服务监控 ==="
|
||||
echo "时间: $(date)"
|
||||
echo ""
|
||||
|
||||
# 显示服务状态
|
||||
echo "📊 服务状态:"
|
||||
docker-compose ps
|
||||
echo ""
|
||||
|
||||
# 显示资源使用
|
||||
echo "💻 资源使用:"
|
||||
docker stats --no-stream --format "table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}"
|
||||
echo ""
|
||||
|
||||
# 显示磁盘使用
|
||||
echo "💾 磁盘使用:"
|
||||
df -h | grep -E "(Filesystem|/dev/)"
|
||||
echo ""
|
||||
|
||||
echo "按 Ctrl+C 退出监控"
|
||||
sleep 5
|
||||
done
|
||||
}
|
||||
|
||||
# 健康检查
|
||||
health_check() {
|
||||
log_step "执行健康检查..."
|
||||
|
||||
local all_healthy=true
|
||||
|
||||
# 检查MySQL
|
||||
if docker-compose exec -T mysql mysqladmin ping -h localhost -u root -p123456 &> /dev/null; then
|
||||
log_info "✅ MySQL服务正常"
|
||||
else
|
||||
log_error "❌ MySQL服务异常"
|
||||
all_healthy=false
|
||||
fi
|
||||
|
||||
# 检查Redis
|
||||
if docker-compose exec -T redis redis-cli ping | grep -q PONG; then
|
||||
log_info "✅ Redis服务正常"
|
||||
else
|
||||
log_error "❌ Redis服务异常"
|
||||
all_healthy=false
|
||||
fi
|
||||
|
||||
# 检查Nacos
|
||||
if curl -s http://localhost:8848/nacos/v1/ns/operator/metrics &> /dev/null; then
|
||||
log_info "✅ Nacos服务正常"
|
||||
else
|
||||
log_error "❌ Nacos服务异常"
|
||||
all_healthy=false
|
||||
fi
|
||||
|
||||
# 检查网关
|
||||
if curl -s http://localhost:9000/actuator/health &> /dev/null; then
|
||||
log_info "✅ 网关服务正常"
|
||||
else
|
||||
log_error "❌ 网关服务异常"
|
||||
all_healthy=false
|
||||
fi
|
||||
|
||||
# 检查AI服务
|
||||
if curl -s http://localhost:9002/actuator/health &> /dev/null; then
|
||||
log_info "✅ AI服务正常"
|
||||
else
|
||||
log_error "❌ AI服务异常"
|
||||
all_healthy=false
|
||||
fi
|
||||
|
||||
# 检查前端
|
||||
if curl -s http://localhost:80/health &> /dev/null; then
|
||||
log_info "✅ 前端服务正常"
|
||||
else
|
||||
log_error "❌ 前端服务异常"
|
||||
all_healthy=false
|
||||
fi
|
||||
|
||||
if $all_healthy; then
|
||||
log_info "🎉 所有服务健康检查通过"
|
||||
else
|
||||
log_warn "⚠️ 部分服务存在问题,请检查日志"
|
||||
fi
|
||||
}
|
||||
|
||||
# 主函数
|
||||
main() {
|
||||
case "${1:-}" in
|
||||
"start")
|
||||
start_services
|
||||
;;
|
||||
"stop")
|
||||
stop_services
|
||||
;;
|
||||
"restart")
|
||||
shift
|
||||
restart_services "$@"
|
||||
;;
|
||||
"status")
|
||||
show_status
|
||||
;;
|
||||
"logs")
|
||||
shift
|
||||
show_logs "$@"
|
||||
;;
|
||||
"backup")
|
||||
backup_data
|
||||
;;
|
||||
"restore")
|
||||
restore_data "$2"
|
||||
;;
|
||||
"update")
|
||||
update_services
|
||||
;;
|
||||
"clean")
|
||||
clean_resources
|
||||
;;
|
||||
"monitor")
|
||||
monitor_services
|
||||
;;
|
||||
"health")
|
||||
health_check
|
||||
;;
|
||||
"-h"|"--help"|"help")
|
||||
show_help
|
||||
;;
|
||||
*)
|
||||
show_help
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
main "$@"
|
||||
@@ -0,0 +1,43 @@
|
||||
情绪博物馆部署包报告
|
||||
==================
|
||||
|
||||
构建信息:
|
||||
- 包名称: emotion-museum-1.0.0-20250713_111829.tar.gz
|
||||
- 构建时间: 20250713_111829
|
||||
- 构建环境: Darwin x86_64
|
||||
|
||||
包内容:
|
||||
- 前端构建产物 ✓
|
||||
- 后端JAR文件 ✓
|
||||
- 数据库脚本 ✓
|
||||
- 部署配置 ✓
|
||||
- Docker配置 ✓
|
||||
- 管理脚本 ✓
|
||||
- 说明文档 ✓
|
||||
|
||||
文件信息:
|
||||
- 压缩包大小: 680K
|
||||
- SHA256校验: 900d585f575b1619e74296496e2fe22f2c2e71b6ad8901d7cab82634765cc10d
|
||||
|
||||
部署要求:
|
||||
- Docker 20.10+
|
||||
- Docker Compose 1.29+
|
||||
- 内存: 4GB+
|
||||
- 磁盘: 10GB+
|
||||
|
||||
快速部署:
|
||||
1. 解压: tar -xzf emotion-museum-1.0.0-20250713_111829.tar.gz
|
||||
2. 进入: cd emotion-museum-1.0.0-20250713_111829
|
||||
3. 配置: vim .env
|
||||
4. 部署: ./quick-deploy.sh
|
||||
|
||||
注意事项:
|
||||
- 请配置正确的Coze API Token
|
||||
- 生产环境请修改默认密码
|
||||
- 建议配置HTTPS证书
|
||||
- 确保防火墙开放必要端口
|
||||
|
||||
技术支持:
|
||||
- 详细文档: DEPLOY.md
|
||||
- 快速指南: QUICK_START.md
|
||||
- 管理命令: ./manage.sh --help
|
||||
@@ -0,0 +1 @@
|
||||
f6fa31c425fbddaea30972db6425265cdad49761236d7a58fcb0fa001baea417 emotion-museum-1.0.0-20250713_123404.tar.gz
|
||||
Binary file not shown.
@@ -0,0 +1,313 @@
|
||||
# 情绪博物馆容器部署指南
|
||||
|
||||
## 📋 概述
|
||||
|
||||
本文档提供了情绪博物馆项目的完整容器化部署方案,支持开发环境和生产环境的快速部署。
|
||||
|
||||
## 🏗️ 架构说明
|
||||
|
||||
### 服务组件
|
||||
- **前端应用** (Vue3 + Ant Design) - 端口: 80/3000
|
||||
- **API网关** (Spring Cloud Gateway) - 端口: 9000
|
||||
- **AI服务** (Spring Boot + Coze API) - 端口: 9002
|
||||
- **用户服务** (Spring Boot) - 端口: 9001
|
||||
- **MySQL数据库** - 端口: 3306
|
||||
- **Redis缓存** - 端口: 6379
|
||||
- **Nacos注册中心** - 端口: 8848
|
||||
- **Nginx反向代理** - 端口: 80/443
|
||||
|
||||
### 网络架构
|
||||
```
|
||||
Internet → Nginx → Frontend/Gateway → Microservices → Database
|
||||
```
|
||||
|
||||
## 🚀 快速开始
|
||||
|
||||
### 1. 系统要求
|
||||
- **操作系统**: Linux/macOS/Windows
|
||||
- **Docker**: 20.10+
|
||||
- **Docker Compose**: 1.29+
|
||||
- **内存**: 最少4GB,推荐8GB+
|
||||
- **磁盘**: 最少10GB可用空间
|
||||
|
||||
### 2. 一键部署
|
||||
```bash
|
||||
# 克隆项目
|
||||
git clone <repository-url>
|
||||
cd EmotionMuseum
|
||||
|
||||
# 快速部署(自动安装依赖)
|
||||
chmod +x quick-deploy.sh
|
||||
./quick-deploy.sh
|
||||
|
||||
# 或者手动部署
|
||||
chmod +x deploy.sh
|
||||
./deploy.sh
|
||||
```
|
||||
|
||||
### 3. 访问应用
|
||||
- **前端应用**: http://localhost
|
||||
- **API文档**: http://localhost:9000/doc.html
|
||||
- **Nacos控制台**: http://localhost:8848/nacos (nacos/nacos)
|
||||
|
||||
## 📁 文件结构
|
||||
|
||||
```
|
||||
EmotionMuseum/
|
||||
├── docker-compose.yml # 开发环境配置
|
||||
├── docker-compose.prod.yml # 生产环境配置
|
||||
├── deploy.sh # 部署脚本
|
||||
├── quick-deploy.sh # 快速部署脚本
|
||||
├── manage.sh # 管理脚本
|
||||
├── .env # 环境变量
|
||||
├── deploy/ # 部署配置
|
||||
│ ├── nginx/ # Nginx配置
|
||||
│ │ ├── nginx.conf
|
||||
│ │ ├── conf.d/
|
||||
│ │ └── ssl/
|
||||
│ ├── mysql/ # MySQL配置
|
||||
│ └── redis/ # Redis配置
|
||||
├── backend/ # 后端服务
|
||||
│ ├── emotion-gateway/
|
||||
│ │ └── Dockerfile
|
||||
│ ├── emotion-ai/
|
||||
│ │ └── Dockerfile
|
||||
│ └── emotion-user/
|
||||
│ └── Dockerfile
|
||||
└── web/ # 前端应用
|
||||
├── Dockerfile
|
||||
└── nginx.conf
|
||||
```
|
||||
|
||||
## ⚙️ 配置说明
|
||||
|
||||
### 环境变量配置
|
||||
编辑 `.env` 文件:
|
||||
```bash
|
||||
# 数据库配置
|
||||
MYSQL_ROOT_PASSWORD=123456
|
||||
MYSQL_DATABASE=emotion_museum
|
||||
MYSQL_USER=emotion
|
||||
MYSQL_PASSWORD=emotion123
|
||||
|
||||
# Coze API配置
|
||||
COZE_API_TOKEN=your-coze-api-token
|
||||
|
||||
# 时区设置
|
||||
TZ=Asia/Shanghai
|
||||
```
|
||||
|
||||
### Nginx配置
|
||||
- **主配置**: `deploy/nginx/nginx.conf`
|
||||
- **站点配置**: `deploy/nginx/conf.d/emotion-museum.conf`
|
||||
- **SSL证书**: `deploy/nginx/ssl/`
|
||||
|
||||
### 数据库配置
|
||||
- **MySQL配置**: `deploy/mysql/conf.d/my.cnf`
|
||||
- **初始化脚本**: `backend/mysql_emotion_museum_final.sql`
|
||||
|
||||
## 🛠️ 管理命令
|
||||
|
||||
### 基础操作
|
||||
```bash
|
||||
# 启动所有服务
|
||||
./manage.sh start
|
||||
|
||||
# 停止所有服务
|
||||
./manage.sh stop
|
||||
|
||||
# 重启所有服务
|
||||
./manage.sh restart
|
||||
|
||||
# 查看服务状态
|
||||
./manage.sh status
|
||||
```
|
||||
|
||||
### 日志管理
|
||||
```bash
|
||||
# 查看所有服务日志
|
||||
./manage.sh logs
|
||||
|
||||
# 跟踪日志输出
|
||||
./manage.sh logs -f
|
||||
|
||||
# 查看特定服务日志
|
||||
./manage.sh logs -s gateway
|
||||
./manage.sh logs -s ai-service
|
||||
```
|
||||
|
||||
### 服务管理
|
||||
```bash
|
||||
# 重启特定服务
|
||||
./manage.sh restart gateway
|
||||
./manage.sh restart ai-service
|
||||
|
||||
# 健康检查
|
||||
./manage.sh health
|
||||
|
||||
# 监控面板
|
||||
./manage.sh monitor
|
||||
```
|
||||
|
||||
### 数据管理
|
||||
```bash
|
||||
# 备份数据
|
||||
./manage.sh backup
|
||||
|
||||
# 恢复数据
|
||||
./manage.sh restore backup_file.tar.gz
|
||||
|
||||
# 更新服务
|
||||
./manage.sh update
|
||||
|
||||
# 清理资源
|
||||
./manage.sh clean
|
||||
```
|
||||
|
||||
## 🔧 生产环境部署
|
||||
|
||||
### 1. 使用生产配置
|
||||
```bash
|
||||
# 使用生产环境配置文件
|
||||
docker-compose -f docker-compose.prod.yml up -d
|
||||
```
|
||||
|
||||
### 2. SSL证书配置
|
||||
```bash
|
||||
# 放置SSL证书
|
||||
cp your-domain.crt deploy/nginx/ssl/emotion-museum.crt
|
||||
cp your-domain.key deploy/nginx/ssl/emotion-museum.key
|
||||
|
||||
# 修改Nginx配置启用HTTPS
|
||||
vim deploy/nginx/conf.d/emotion-museum.conf
|
||||
```
|
||||
|
||||
### 3. 域名配置
|
||||
修改 `deploy/nginx/conf.d/emotion-museum.conf`:
|
||||
```nginx
|
||||
server_name your-domain.com www.your-domain.com;
|
||||
```
|
||||
|
||||
### 4. 防火墙配置
|
||||
```bash
|
||||
# Ubuntu/Debian
|
||||
sudo ufw allow 80/tcp
|
||||
sudo ufw allow 443/tcp
|
||||
|
||||
# CentOS/RHEL
|
||||
sudo firewall-cmd --permanent --add-port=80/tcp
|
||||
sudo firewall-cmd --permanent --add-port=443/tcp
|
||||
sudo firewall-cmd --reload
|
||||
```
|
||||
|
||||
## 📊 监控和维护
|
||||
|
||||
### 服务监控
|
||||
```bash
|
||||
# 实时监控
|
||||
./manage.sh monitor
|
||||
|
||||
# 资源使用情况
|
||||
docker stats
|
||||
|
||||
# 服务状态
|
||||
docker-compose ps
|
||||
```
|
||||
|
||||
### 日志查看
|
||||
```bash
|
||||
# 应用日志
|
||||
./manage.sh logs -f
|
||||
|
||||
# 系统日志
|
||||
tail -f logs/nginx/access.log
|
||||
tail -f logs/mysql/error.log
|
||||
```
|
||||
|
||||
### 性能优化
|
||||
1. **数据库优化**: 调整 `deploy/mysql/conf.d/my.cnf`
|
||||
2. **Redis优化**: 调整 `deploy/redis/redis.conf`
|
||||
3. **Nginx优化**: 调整 `deploy/nginx/nginx.conf`
|
||||
4. **JVM优化**: 修改Dockerfile中的JVM参数
|
||||
|
||||
## 🔒 安全配置
|
||||
|
||||
### 1. 数据库安全
|
||||
- 修改默认密码
|
||||
- 限制访问IP
|
||||
- 启用SSL连接
|
||||
|
||||
### 2. Redis安全
|
||||
- 设置密码认证
|
||||
- 绑定特定IP
|
||||
- 禁用危险命令
|
||||
|
||||
### 3. Nginx安全
|
||||
- 启用HTTPS
|
||||
- 配置安全头
|
||||
- 限制请求频率
|
||||
|
||||
### 4. 应用安全
|
||||
- 配置JWT密钥
|
||||
- 启用CORS限制
|
||||
- 设置API限流
|
||||
|
||||
## 🚨 故障排除
|
||||
|
||||
### 常见问题
|
||||
|
||||
#### 1. 服务启动失败
|
||||
```bash
|
||||
# 查看服务日志
|
||||
./manage.sh logs -s service-name
|
||||
|
||||
# 检查端口占用
|
||||
netstat -tlnp | grep :port
|
||||
|
||||
# 重启服务
|
||||
./manage.sh restart service-name
|
||||
```
|
||||
|
||||
#### 2. 数据库连接失败
|
||||
```bash
|
||||
# 检查MySQL状态
|
||||
docker-compose exec mysql mysqladmin ping -u root -p
|
||||
|
||||
# 查看数据库日志
|
||||
./manage.sh logs -s mysql
|
||||
```
|
||||
|
||||
#### 3. 前端访问异常
|
||||
```bash
|
||||
# 检查Nginx配置
|
||||
nginx -t
|
||||
|
||||
# 查看Nginx日志
|
||||
./manage.sh logs -s nginx
|
||||
```
|
||||
|
||||
#### 4. API调用失败
|
||||
```bash
|
||||
# 检查网关状态
|
||||
curl http://localhost:9000/actuator/health
|
||||
|
||||
# 查看网关日志
|
||||
./manage.sh logs -s gateway
|
||||
```
|
||||
|
||||
### 性能问题
|
||||
1. **内存不足**: 增加服务器内存或调整JVM参数
|
||||
2. **磁盘空间**: 清理日志文件和Docker镜像
|
||||
3. **网络延迟**: 检查服务间网络连接
|
||||
|
||||
## 📞 技术支持
|
||||
|
||||
如遇到问题,请:
|
||||
1. 查看相关服务日志
|
||||
2. 检查配置文件
|
||||
3. 参考故障排除指南
|
||||
4. 联系技术支持团队
|
||||
|
||||
---
|
||||
|
||||
**部署完成后,请及时修改默认密码和配置文件中的敏感信息!**
|
||||
@@ -0,0 +1,283 @@
|
||||
# 情绪博物馆测试环境快速部署指南
|
||||
|
||||
## 📦 包内容说明
|
||||
|
||||
```
|
||||
emotion-museum-1.0.0-YYYYMMDD_HHMMSS/
|
||||
├── frontend/ # 前端构建产物
|
||||
│ ├── assets/ # 静态资源
|
||||
│ ├── index.html # 主页面
|
||||
│ ├── Dockerfile # 前端容器配置
|
||||
│ ├── nginx.conf # Nginx配置
|
||||
│ └── config/ # 前端配置
|
||||
├── backend/ # 后端JAR文件
|
||||
│ ├── emotion-gateway-*.jar # 网关服务
|
||||
│ ├── emotion-ai-*.jar # AI服务
|
||||
│ ├── emotion-user-*.jar # 用户服务
|
||||
│ ├── config/ # 配置文件
|
||||
│ │ ├── application-test.yml
|
||||
│ │ ├── gateway-test.yml
|
||||
│ │ └── ai-test.yml
|
||||
│ ├── gateway-Dockerfile # 网关容器配置
|
||||
│ ├── ai-Dockerfile # AI服务容器配置
|
||||
│ └── user-Dockerfile # 用户服务容器配置
|
||||
├── database/ # 数据库脚本
|
||||
│ ├── mysql_emotion_museum_final.sql
|
||||
│ └── verify-database-script.sql
|
||||
├── deploy/ # 部署配置
|
||||
│ ├── nginx/conf.d/ # Nginx配置
|
||||
│ ├── mysql/conf.d/ # MySQL配置
|
||||
│ └── redis/ # Redis配置
|
||||
├── docker-compose.yml # 默认配置
|
||||
├── docker-compose.test.yml # 测试环境配置
|
||||
├── deploy.sh # 主部署脚本
|
||||
├── install-environment.sh # 环境安装脚本
|
||||
├── init-database.sh # 数据库初始化脚本
|
||||
├── manage.sh # 管理脚本(兼容)
|
||||
├── .env.test # 测试环境变量
|
||||
├── README.md # 快速开始指南
|
||||
├── VERSION.txt # 版本信息
|
||||
├── DEPLOY.md # 详细部署文档
|
||||
└── QUICK_START.md # 本文件
|
||||
```
|
||||
|
||||
## 🚀 快速部署步骤
|
||||
|
||||
### 1. 系统要求
|
||||
- **操作系统**: Linux/macOS (推荐 Ubuntu 20.04+)
|
||||
- **内存**: 最少4GB,推荐8GB+
|
||||
- **磁盘**: 最少20GB可用空间
|
||||
- **网络**: 能够访问互联网
|
||||
|
||||
### 2. 部署步骤
|
||||
|
||||
#### 方式一:一键部署(推荐)
|
||||
```bash
|
||||
# 1. 解压部署包
|
||||
tar -xzf emotion-museum-*.tar.gz
|
||||
cd emotion-museum-*
|
||||
|
||||
# 2. 配置环境变量(重要)
|
||||
vim .env.test
|
||||
# 修改 SERVER_IP 为实际IP
|
||||
# 配置 COZE_API_TOKEN
|
||||
|
||||
# 3. 一键部署(包含环境安装、数据库初始化、服务部署)
|
||||
chmod +x deploy.sh
|
||||
./deploy.sh
|
||||
```
|
||||
|
||||
#### 方式二:分步部署
|
||||
```bash
|
||||
# 1. 解压部署包
|
||||
tar -xzf emotion-museum-*.tar.gz
|
||||
cd emotion-museum-*
|
||||
|
||||
# 2. 配置环境变量
|
||||
vim .env.test
|
||||
|
||||
# 3. 分步部署
|
||||
chmod +x deploy.sh
|
||||
./deploy.sh install-env # 安装环境
|
||||
./deploy.sh init-db # 初始化数据库
|
||||
./deploy.sh build # 构建镜像
|
||||
./deploy.sh start # 启动服务
|
||||
```
|
||||
|
||||
#### 方式三:跳过某些步骤
|
||||
```bash
|
||||
# 如果已安装环境,跳过环境安装
|
||||
./deploy.sh --skip-env
|
||||
|
||||
# 如果已初始化数据库,跳过数据库初始化
|
||||
./deploy.sh --skip-db
|
||||
|
||||
# 启用调试模式
|
||||
./deploy.sh --debug
|
||||
```
|
||||
|
||||
### 3. 验证部署
|
||||
```bash
|
||||
# 查看服务状态
|
||||
./deploy.sh status
|
||||
|
||||
# 健康检查
|
||||
./deploy.sh health
|
||||
|
||||
# 查看日志
|
||||
./deploy.sh logs
|
||||
```
|
||||
|
||||
### 4. 访问应用
|
||||
- **前端应用**: http://localhost (或 http://your-server-ip)
|
||||
- **API网关**: http://localhost:9000
|
||||
- **Nacos控制台**: http://localhost:8848/nacos (nacos/nacos)
|
||||
|
||||
## ⚙️ 配置说明
|
||||
|
||||
### 必须配置项
|
||||
编辑 `.env.test` 文件中的以下配置:
|
||||
|
||||
```bash
|
||||
# 服务器IP(重要:修改为实际IP)
|
||||
SERVER_IP=your-server-ip
|
||||
|
||||
# Coze API配置(必须)
|
||||
COZE_API_TOKEN=your-actual-coze-api-token
|
||||
|
||||
# 数据库密码(建议修改)
|
||||
MYSQL_ROOT_PASSWORD=your-secure-password
|
||||
MYSQL_PASSWORD=your-secure-password
|
||||
|
||||
# JWT密钥(建议修改)
|
||||
JWT_SECRET=your-production-jwt-secret-key
|
||||
```
|
||||
|
||||
### 可选配置项
|
||||
```bash
|
||||
# 时区设置
|
||||
TZ=Asia/Shanghai
|
||||
|
||||
# 端口配置
|
||||
GATEWAY_PORT=9000
|
||||
USER_SERVICE_PORT=9001
|
||||
AI_SERVICE_PORT=9002
|
||||
|
||||
# 日志和存储路径
|
||||
LOG_PATH=/data/logs/emotion-museum
|
||||
UPLOAD_PATH=/data/uploads/emotion-museum
|
||||
```
|
||||
|
||||
## 🛠️ 管理命令
|
||||
|
||||
```bash
|
||||
# 主要部署命令
|
||||
./deploy.sh # 完整部署
|
||||
./deploy.sh start # 启动服务
|
||||
./deploy.sh stop # 停止服务
|
||||
./deploy.sh restart # 重启服务
|
||||
./deploy.sh status # 查看状态
|
||||
|
||||
# 日志管理
|
||||
./deploy.sh logs # 查看所有日志
|
||||
./deploy.sh logs -f # 跟踪日志
|
||||
./deploy.sh logs gateway # 查看网关日志
|
||||
./deploy.sh logs ai-service # 查看AI服务日志
|
||||
|
||||
# 数据管理
|
||||
./deploy.sh backup # 备份数据
|
||||
./deploy.sh health # 健康检查
|
||||
./deploy.sh clean # 清理资源
|
||||
|
||||
# 独立脚本
|
||||
./install-environment.sh # 安装环境
|
||||
./init-database.sh # 初始化数据库
|
||||
|
||||
# 兼容命令(旧版本)
|
||||
./manage.sh start # 启动服务
|
||||
./manage.sh status # 查看状态
|
||||
```
|
||||
|
||||
## 🔧 生产环境配置
|
||||
|
||||
### 1. 使用生产配置
|
||||
```bash
|
||||
# 使用生产环境配置
|
||||
docker-compose -f docker-compose.prod.yml up -d
|
||||
```
|
||||
|
||||
### 2. 配置HTTPS
|
||||
```bash
|
||||
# 1. 放置SSL证书
|
||||
cp your-domain.crt deploy/nginx/ssl/emotion-museum.crt
|
||||
cp your-domain.key deploy/nginx/ssl/emotion-museum.key
|
||||
|
||||
# 2. 修改Nginx配置
|
||||
vim deploy/nginx/conf.d/emotion-museum.conf
|
||||
# 取消HTTPS相关配置的注释
|
||||
|
||||
# 3. 重启Nginx
|
||||
docker-compose restart nginx
|
||||
```
|
||||
|
||||
### 3. 配置域名
|
||||
```bash
|
||||
# 修改Nginx配置中的域名
|
||||
vim deploy/nginx/conf.d/emotion-museum.conf
|
||||
# 将 localhost 替换为您的域名
|
||||
```
|
||||
|
||||
## 🚨 故障排除
|
||||
|
||||
### 常见问题
|
||||
|
||||
1. **环境安装失败**
|
||||
```bash
|
||||
# 检查系统要求
|
||||
./install-environment.sh verify
|
||||
|
||||
# 手动安装特定组件
|
||||
./install-environment.sh docker
|
||||
```
|
||||
|
||||
2. **端口冲突**
|
||||
```bash
|
||||
# 检查端口占用
|
||||
netstat -tlnp | grep :80
|
||||
netstat -tlnp | grep :3306
|
||||
|
||||
# 修改 .env.test 中的端口配置
|
||||
```
|
||||
|
||||
3. **数据库初始化失败**
|
||||
```bash
|
||||
# 查看MySQL容器日志
|
||||
docker logs emotion-mysql
|
||||
|
||||
# 重新初始化
|
||||
./init-database.sh clean
|
||||
./init-database.sh
|
||||
```
|
||||
|
||||
4. **服务启动失败**
|
||||
```bash
|
||||
# 查看服务日志
|
||||
./deploy.sh logs service-name
|
||||
|
||||
# 查看容器状态
|
||||
docker ps -a
|
||||
```
|
||||
|
||||
5. **网络连接问题**
|
||||
```bash
|
||||
# 检查Docker网络
|
||||
docker network ls
|
||||
|
||||
# 健康检查
|
||||
./deploy.sh health
|
||||
```
|
||||
|
||||
### 获取帮助
|
||||
- 查看详细文档: `cat DEPLOY.md`
|
||||
- 查看快速指南: `cat README.md`
|
||||
- 查看版本信息: `cat VERSION.txt`
|
||||
- 查看部署命令: `./deploy.sh --help`
|
||||
|
||||
## 📞 技术支持
|
||||
|
||||
如遇到问题,请按以下步骤排查:
|
||||
|
||||
1. **查看详细日志**:`./deploy.sh logs --debug`
|
||||
2. **检查服务状态**:`./deploy.sh status`
|
||||
3. **验证配置文件**:检查 `.env.test` 配置
|
||||
4. **查看详细文档**:`DEPLOY.md`
|
||||
5. **重新部署**:`./deploy.sh clean && ./deploy.sh`
|
||||
|
||||
## 📝 重要提醒
|
||||
|
||||
- ⚠️ **首次部署**:请务必修改 `.env.test` 中的 `SERVER_IP` 和 `COZE_API_TOKEN`
|
||||
- ⚠️ **生产环境**:请修改所有默认密码和密钥
|
||||
- ⚠️ **防火墙**:确保开放必要的端口 (80, 3306, 6379, 8848, 9000-9002)
|
||||
|
||||
---
|
||||
**部署完成后,请及时修改默认密码和敏感配置!**
|
||||
@@ -0,0 +1,29 @@
|
||||
情绪博物馆 - 版本信息
|
||||
========================
|
||||
|
||||
项目名称: emotion-museum
|
||||
版本号: 1.0.0
|
||||
构建时间: 20250713_123404
|
||||
构建环境: Darwin x86_64
|
||||
|
||||
前端信息:
|
||||
- Node.js: v16.20.2
|
||||
- npm: 8.19.4
|
||||
|
||||
后端信息:
|
||||
- Java: java 20 2023-03-21
|
||||
- Maven: Apache Maven 3.9.9 (8e8579a9e76f7d015ee5ec7bfcdc97d260186937)
|
||||
|
||||
Git信息:
|
||||
- 分支: main
|
||||
- 提交: ec81706
|
||||
- 时间: Mon May 26 20:04:17 2025 +0800
|
||||
|
||||
文件清单:
|
||||
- 前端构建产物: frontend/
|
||||
- 后端JAR文件: backend/
|
||||
- 数据库脚本: database/
|
||||
- 部署配置: deploy/
|
||||
- Docker配置: docker-compose*.yml
|
||||
- 部署脚本: *.sh
|
||||
- 说明文档: *.md
|
||||
@@ -0,0 +1,48 @@
|
||||
# AI服务Dockerfile
|
||||
FROM openjdk:17-jdk-alpine
|
||||
|
||||
# 设置工作目录
|
||||
WORKDIR /app
|
||||
|
||||
# 安装必要的工具
|
||||
RUN apk add --no-cache curl tzdata && \
|
||||
cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
|
||||
echo "Asia/Shanghai" > /etc/timezone
|
||||
|
||||
# 复制Maven构建文件
|
||||
COPY pom.xml ./
|
||||
COPY emotion-common ./emotion-common
|
||||
COPY emotion-ai ./emotion-ai
|
||||
|
||||
# 安装Maven
|
||||
RUN apk add --no-cache maven
|
||||
|
||||
# 构建应用
|
||||
RUN mvn clean package -DskipTests -pl emotion-ai -am
|
||||
|
||||
# 创建运行用户
|
||||
RUN addgroup -g 1000 emotion && \
|
||||
adduser -D -s /bin/sh -u 1000 -G emotion emotion
|
||||
|
||||
# 复制jar文件
|
||||
RUN cp emotion-ai/target/emotion-ai-*.jar app.jar
|
||||
|
||||
# 设置文件权限
|
||||
RUN chown -R emotion:emotion /app
|
||||
|
||||
# 切换到非root用户
|
||||
USER emotion
|
||||
|
||||
# 健康检查
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
|
||||
CMD curl -f http://localhost:9002/actuator/health || exit 1
|
||||
|
||||
# 暴露端口
|
||||
EXPOSE 9002
|
||||
|
||||
# 启动命令
|
||||
ENTRYPOINT ["java", "-jar", \
|
||||
"-Xms512m", "-Xmx1024m", \
|
||||
"-Djava.security.egd=file:/dev/./urandom", \
|
||||
"-Dspring.profiles.active=docker", \
|
||||
"app.jar"]
|
||||
@@ -0,0 +1,80 @@
|
||||
# 用户服务 Docker环境配置
|
||||
server:
|
||||
port: 9001
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: emotion-user
|
||||
profiles:
|
||||
active: docker
|
||||
cloud:
|
||||
nacos:
|
||||
discovery:
|
||||
server-addr: ${NACOS_SERVER_ADDR:nacos:8848}
|
||||
namespace: public
|
||||
group: DEFAULT_GROUP
|
||||
config:
|
||||
server-addr: ${NACOS_SERVER_ADDR:nacos:8848}
|
||||
file-extension: yml
|
||||
namespace: public
|
||||
group: DEFAULT_GROUP
|
||||
datasource:
|
||||
url: jdbc:mysql://${MYSQL_HOST:mysql}:${MYSQL_PORT:3306}/emotion_museum?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
|
||||
username: root
|
||||
password: 123456
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
hikari:
|
||||
pool-name: EmotionUserHikariCP
|
||||
minimum-idle: 5
|
||||
maximum-pool-size: 20
|
||||
auto-commit: true
|
||||
idle-timeout: 30000
|
||||
max-lifetime: 1800000
|
||||
connection-timeout: 30000
|
||||
data:
|
||||
redis:
|
||||
host: ${REDIS_HOST:redis}
|
||||
port: ${REDIS_PORT:6379}
|
||||
password:
|
||||
database: 2
|
||||
timeout: 6000ms
|
||||
lettuce:
|
||||
pool:
|
||||
max-active: 8
|
||||
max-wait: -1ms
|
||||
max-idle: 8
|
||||
min-idle: 0
|
||||
|
||||
# MyBatis Plus配置
|
||||
mybatis-plus:
|
||||
configuration:
|
||||
map-underscore-to-camel-case: true
|
||||
cache-enabled: false
|
||||
call-setters-on-nulls: true
|
||||
jdbc-type-for-null: 'null'
|
||||
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
||||
global-config:
|
||||
db-config:
|
||||
id-type: assign_uuid
|
||||
logic-delete-field: isDeleted
|
||||
logic-delete-value: 1
|
||||
logic-not-delete-value: 0
|
||||
banner: false
|
||||
|
||||
# 日志配置
|
||||
logging:
|
||||
level:
|
||||
com.emotionmuseum: DEBUG
|
||||
com.emotionmuseum.user.mapper: DEBUG
|
||||
pattern:
|
||||
console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level [%logger{50}] - %msg%n"
|
||||
|
||||
# 管理端点
|
||||
management:
|
||||
endpoints:
|
||||
web:
|
||||
exposure:
|
||||
include: health,info,metrics,prometheus
|
||||
endpoint:
|
||||
health:
|
||||
show-details: always
|
||||
@@ -0,0 +1,79 @@
|
||||
server:
|
||||
port: 9001
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: emotion-user
|
||||
profiles:
|
||||
active: dev
|
||||
datasource:
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
url: jdbc:mysql://localhost:3306/emotion_museum?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true
|
||||
username: root
|
||||
password: 123456
|
||||
hikari:
|
||||
minimum-idle: 5
|
||||
maximum-pool-size: 20
|
||||
idle-timeout: 600000
|
||||
max-lifetime: 1800000
|
||||
connection-timeout: 30000
|
||||
data:
|
||||
redis:
|
||||
host: localhost
|
||||
port: 6379
|
||||
database: 0
|
||||
timeout: 3000ms
|
||||
lettuce:
|
||||
pool:
|
||||
max-active: 20
|
||||
max-idle: 10
|
||||
min-idle: 5
|
||||
max-wait: 3000ms
|
||||
cloud:
|
||||
nacos:
|
||||
discovery:
|
||||
server-addr: localhost:8848
|
||||
namespace: emotion-dev
|
||||
group: DEFAULT_GROUP
|
||||
enabled: false
|
||||
config:
|
||||
enabled: false
|
||||
|
||||
mybatis-plus:
|
||||
configuration:
|
||||
map-underscore-to-camel-case: true
|
||||
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
|
||||
global-config:
|
||||
db-config:
|
||||
id-type: assign_uuid
|
||||
logic-delete-field: deleted
|
||||
logic-delete-value: 1
|
||||
logic-not-delete-value: 0
|
||||
|
||||
# 监控配置
|
||||
management:
|
||||
endpoints:
|
||||
web:
|
||||
exposure:
|
||||
include: health,info,metrics,prometheus
|
||||
endpoint:
|
||||
health:
|
||||
show-details: always
|
||||
metrics:
|
||||
export:
|
||||
prometheus:
|
||||
enabled: true
|
||||
|
||||
# 日志配置
|
||||
logging:
|
||||
level:
|
||||
com.emotionmuseum: debug
|
||||
com.baomidou.mybatisplus: debug
|
||||
pattern:
|
||||
console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level [%logger{50}] - %msg%n"
|
||||
|
||||
# JWT配置
|
||||
jwt:
|
||||
secret: emotion-museum-secret-key-2025
|
||||
expiration: 86400
|
||||
refresh-expiration: 604800
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,48 @@
|
||||
# 网关服务Dockerfile
|
||||
FROM openjdk:17-jdk-alpine
|
||||
|
||||
# 设置工作目录
|
||||
WORKDIR /app
|
||||
|
||||
# 安装必要的工具
|
||||
RUN apk add --no-cache curl tzdata && \
|
||||
cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
|
||||
echo "Asia/Shanghai" > /etc/timezone
|
||||
|
||||
# 复制Maven构建文件
|
||||
COPY pom.xml ./
|
||||
COPY emotion-common ./emotion-common
|
||||
COPY emotion-gateway ./emotion-gateway
|
||||
|
||||
# 安装Maven
|
||||
RUN apk add --no-cache maven
|
||||
|
||||
# 构建应用
|
||||
RUN mvn clean package -DskipTests -pl emotion-gateway -am
|
||||
|
||||
# 创建运行用户
|
||||
RUN addgroup -g 1000 emotion && \
|
||||
adduser -D -s /bin/sh -u 1000 -G emotion emotion
|
||||
|
||||
# 复制jar文件
|
||||
RUN cp emotion-gateway/target/emotion-gateway-*.jar app.jar
|
||||
|
||||
# 设置文件权限
|
||||
RUN chown -R emotion:emotion /app
|
||||
|
||||
# 切换到非root用户
|
||||
USER emotion
|
||||
|
||||
# 健康检查
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
|
||||
CMD curl -f http://localhost:9000/actuator/health || exit 1
|
||||
|
||||
# 暴露端口
|
||||
EXPOSE 9000
|
||||
|
||||
# 启动命令
|
||||
ENTRYPOINT ["java", "-jar", \
|
||||
"-Xms512m", "-Xmx1024m", \
|
||||
"-Djava.security.egd=file:/dev/./urandom", \
|
||||
"-Dspring.profiles.active=docker", \
|
||||
"app.jar"]
|
||||
@@ -0,0 +1,48 @@
|
||||
# 用户服务Dockerfile
|
||||
FROM openjdk:17-jdk-alpine
|
||||
|
||||
# 设置工作目录
|
||||
WORKDIR /app
|
||||
|
||||
# 安装必要的工具
|
||||
RUN apk add --no-cache curl tzdata && \
|
||||
cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
|
||||
echo "Asia/Shanghai" > /etc/timezone
|
||||
|
||||
# 复制Maven构建文件
|
||||
COPY pom.xml ./
|
||||
COPY emotion-common ./emotion-common
|
||||
COPY emotion-user ./emotion-user
|
||||
|
||||
# 安装Maven
|
||||
RUN apk add --no-cache maven
|
||||
|
||||
# 构建应用
|
||||
RUN mvn clean package -DskipTests -pl emotion-user -am
|
||||
|
||||
# 创建运行用户
|
||||
RUN addgroup -g 1000 emotion && \
|
||||
adduser -D -s /bin/sh -u 1000 -G emotion emotion
|
||||
|
||||
# 复制jar文件
|
||||
RUN cp emotion-user/target/emotion-user-*.jar app.jar
|
||||
|
||||
# 设置文件权限
|
||||
RUN chown -R emotion:emotion /app
|
||||
|
||||
# 切换到非root用户
|
||||
USER emotion
|
||||
|
||||
# 健康检查
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
|
||||
CMD curl -f http://localhost:9001/actuator/health || exit 1
|
||||
|
||||
# 暴露端口
|
||||
EXPOSE 9001
|
||||
|
||||
# 启动命令
|
||||
ENTRYPOINT ["java", "-jar", \
|
||||
"-Xms512m", "-Xmx1024m", \
|
||||
"-Djava.security.egd=file:/dev/./urandom", \
|
||||
"-Dspring.profiles.active=docker", \
|
||||
"app.jar"]
|
||||
+819
@@ -0,0 +1,819 @@
|
||||
-- ============================================================================
|
||||
-- 情绪博物馆数据库完整部署脚本
|
||||
-- 版本: v3.0 Final (雪花算法主键版本) - 开发版本
|
||||
-- 创建时间: 2025-07-13
|
||||
-- 数据库类型: MySQL 8.0+
|
||||
-- 说明: 包含完整表结构、索引、初始数据的一体化部署脚本
|
||||
-- 主键类型: VARCHAR(36) 使用雪花算法生成,避免前端精度丢失问题
|
||||
-- 关联策略: 不使用外键约束,通过代码中的ID字段关联
|
||||
-- 特性: 开发阶段 - 先删除表再重新创建,确保表结构是最新的
|
||||
-- 警告: 此脚本会删除现有表和数据,仅适用于开发环境!
|
||||
-- ============================================================================
|
||||
-- 设置SQL模式和字符集
|
||||
SET
|
||||
SQL_MODE = 'NO_AUTO_VALUE_ON_ZERO';
|
||||
|
||||
SET
|
||||
AUTOCOMMIT = 0;
|
||||
|
||||
START TRANSACTION;
|
||||
|
||||
SET
|
||||
time_zone = "+00:00";
|
||||
|
||||
-- 创建数据库
|
||||
CREATE DATABASE IF NOT EXISTS emotion_museum DEFAULT CHARACTER
|
||||
SET
|
||||
utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
USE emotion_museum;
|
||||
|
||||
-- ============================================================================
|
||||
-- 数据库设计原则
|
||||
-- ============================================================================
|
||||
-- 1. 主键策略: 使用VARCHAR(36)雪花算法ID,避免前端精度丢失
|
||||
-- 2. 关联策略: 不使用外键约束,通过代码中的ID字段维护关联关系
|
||||
-- 3. 公共字段: 所有表继承BaseEntity的公共字段
|
||||
-- 4. 索引优化: 为查询频繁的字段创建合适的索引
|
||||
-- 5. 字符集: 统一使用utf8mb4支持emoji和特殊字符
|
||||
-- ============================================================================
|
||||
-- 删除现有表(开发阶段确保表结构最新)
|
||||
-- 警告: 这会删除所有数据!
|
||||
-- ============================================================================
|
||||
DROP TABLE IF EXISTS user_stats;
|
||||
|
||||
DROP TABLE IF EXISTS guest_user;
|
||||
|
||||
DROP TABLE IF EXISTS reward;
|
||||
|
||||
DROP TABLE IF EXISTS achievement;
|
||||
|
||||
DROP TABLE IF EXISTS comment;
|
||||
|
||||
DROP TABLE IF EXISTS community_post;
|
||||
|
||||
DROP TABLE IF EXISTS location_pin;
|
||||
|
||||
DROP TABLE IF EXISTS topic_interaction;
|
||||
|
||||
DROP TABLE IF EXISTS growth_topic;
|
||||
|
||||
DROP TABLE IF EXISTS emotion_record;
|
||||
|
||||
DROP TABLE IF EXISTS emotion_analysis;
|
||||
|
||||
DROP TABLE IF EXISTS coze_api_call;
|
||||
|
||||
DROP TABLE IF EXISTS message;
|
||||
|
||||
DROP TABLE IF EXISTS conversation;
|
||||
|
||||
DROP TABLE IF EXISTS user;
|
||||
|
||||
-- ============================================================================
|
||||
-- 1. 用户表 (user)
|
||||
-- ============================================================================
|
||||
CREATE TABLE user (
|
||||
id VARCHAR(36) PRIMARY KEY, -- UUID主键
|
||||
account VARCHAR(50) NOT NULL UNIQUE, -- 账号
|
||||
password VARCHAR(255) NOT NULL, -- 密码(加密后)
|
||||
username VARCHAR(50) NOT NULL UNIQUE, -- 用户名
|
||||
email VARCHAR(100) NOT NULL UNIQUE, -- 邮箱
|
||||
phone VARCHAR(20) UNIQUE, -- 手机号
|
||||
avatar VARCHAR(500), -- 头像URL
|
||||
nickname VARCHAR(50) NOT NULL, -- 昵称
|
||||
birth_date DATE, -- 生日
|
||||
location VARCHAR(100), -- 所在地
|
||||
bio TEXT, -- 个人简介
|
||||
member_level VARCHAR(20) NOT NULL DEFAULT 'free', -- 会员等级
|
||||
total_days INT NOT NULL DEFAULT 0, -- 使用天数
|
||||
-- 成长数据
|
||||
self_awareness DECIMAL(5, 2) NOT NULL DEFAULT 50.00, -- 自我感知
|
||||
emotional_resilience DECIMAL(5, 2) NOT NULL DEFAULT 50.00, -- 情绪韧性
|
||||
action_power DECIMAL(5, 2) NOT NULL DEFAULT 50.00, -- 行动力
|
||||
empathy DECIMAL(5, 2) NOT NULL DEFAULT 50.00, -- 共情力
|
||||
life_enthusiasm DECIMAL(5, 2) NOT NULL DEFAULT 50.00, -- 生活热度
|
||||
-- 状态字段
|
||||
status TINYINT NOT NULL DEFAULT 1, -- 状态: 0-禁用, 1-正常
|
||||
is_verified TINYINT NOT NULL DEFAULT 0, -- 是否已验证: 0-未验证, 1-已验证
|
||||
last_active_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 最后活跃时间
|
||||
-- 公共字段
|
||||
create_by VARCHAR(36), -- 创建人ID
|
||||
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 创建时间
|
||||
update_by VARCHAR(36), -- 更新人ID
|
||||
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
|
||||
is_deleted TINYINT NOT NULL DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
|
||||
remarks VARCHAR(500) -- 备注
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户表';
|
||||
|
||||
-- ============================================================================
|
||||
-- 2. 对话表 (conversation)
|
||||
-- 关联说明: user_id 关联 user.id,通过代码逻辑维护关联关系
|
||||
-- ============================================================================
|
||||
CREATE TABLE conversation (
|
||||
id VARCHAR(36) PRIMARY KEY, -- UUID主键
|
||||
user_id VARCHAR(36) NOT NULL, -- 用户ID (关联user.id)
|
||||
user_type VARCHAR(20) NOT NULL DEFAULT 'registered', -- 用户类型: registered-注册用户, guest-访客用户
|
||||
title VARCHAR(200), -- 对话标题
|
||||
type VARCHAR(50) NOT NULL DEFAULT 'emotion_chat', -- 对话类型
|
||||
status VARCHAR(20) NOT NULL DEFAULT 'active', -- 状态: active-活跃, ended-结束, archived-归档
|
||||
coze_conversation_id VARCHAR(100), -- Coze对话ID
|
||||
bot_id VARCHAR(50), -- 使用的Bot ID
|
||||
workflow_id VARCHAR(50), -- 使用的Workflow ID
|
||||
initial_message TEXT, -- 初始消息
|
||||
context TEXT, -- 上下文信息
|
||||
primary_emotion VARCHAR(50), -- 主要情绪
|
||||
emotion_intensity DECIMAL(3, 2), -- 情绪强度
|
||||
emotion_trend VARCHAR(50), -- 情绪趋势
|
||||
keywords JSON, -- 关键词
|
||||
ai_insights TEXT, -- AI洞察
|
||||
confidence DECIMAL(3, 2), -- 分析置信度
|
||||
start_time DATETIME, -- 开始时间
|
||||
end_time DATETIME, -- 结束时间
|
||||
last_active_time DATETIME DEFAULT CURRENT_TIMESTAMP, -- 最后活跃时间
|
||||
message_count INT NOT NULL DEFAULT 0, -- 消息数量
|
||||
total_tokens INT DEFAULT 0, -- 总Token使用量
|
||||
total_cost DECIMAL(10, 4) DEFAULT 0.0000, -- 总费用
|
||||
client_ip VARCHAR(45), -- 客户端IP地址 (支持IPv6)
|
||||
user_agent TEXT, -- 用户代理信息
|
||||
summary TEXT, -- 对话摘要
|
||||
tags JSON, -- 标签
|
||||
metadata JSON, -- 扩展元数据
|
||||
-- 公共字段
|
||||
create_by VARCHAR(36), -- 创建人ID
|
||||
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 创建时间
|
||||
update_by VARCHAR(36), -- 更新人ID
|
||||
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
|
||||
is_deleted TINYINT NOT NULL DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
|
||||
remarks VARCHAR(500) -- 备注
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '对话表';
|
||||
|
||||
-- ============================================================================
|
||||
-- 3. 消息表 (message)
|
||||
-- 关联说明: conversation_id 关联 conversation.id,通过代码逻辑维护关联关系
|
||||
-- ============================================================================
|
||||
CREATE TABLE message (
|
||||
id VARCHAR(36) PRIMARY KEY, -- UUID主键
|
||||
conversation_id VARCHAR(36) NOT NULL, -- 对话ID (关联conversation.id)
|
||||
content TEXT NOT NULL, -- 消息内容
|
||||
type VARCHAR(50) NOT NULL DEFAULT 'text', -- 消息类型
|
||||
sender VARCHAR(20) NOT NULL, -- 发送者: user-用户, assistant-AI助手
|
||||
timestamp DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 消息时间戳
|
||||
coze_chat_id VARCHAR(50), -- Coze平台的聊天ID
|
||||
coze_message_id VARCHAR(50), -- Coze平台的消息ID
|
||||
status VARCHAR(20) DEFAULT 'sent', -- 消息状态: sending/sent/failed/processing
|
||||
error_message TEXT, -- 错误信息
|
||||
emotion_score DECIMAL(3, 2), -- 情绪评分
|
||||
emotion_type VARCHAR(50), -- 情绪类型
|
||||
emotion_confidence DECIMAL(3, 2), -- 情绪分析置信度
|
||||
prompt_tokens INT DEFAULT 0, -- 输入Token数
|
||||
completion_tokens INT DEFAULT 0, -- 输出Token数
|
||||
total_tokens INT DEFAULT 0, -- 总Token数
|
||||
api_cost DECIMAL(10, 6) DEFAULT 0.000000, -- API调用费用
|
||||
is_read TINYINT NOT NULL DEFAULT 0, -- 是否已读: 0-未读, 1-已读
|
||||
parent_message_id VARCHAR(36), -- 父消息ID(用于回复链)
|
||||
emotion_analysis JSON, -- 情绪分析结果
|
||||
metadata JSON, -- 扩展元数据
|
||||
-- 公共字段
|
||||
create_by VARCHAR(36), -- 创建人ID
|
||||
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 创建时间
|
||||
update_by VARCHAR(36), -- 更新人ID
|
||||
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
|
||||
is_deleted TINYINT NOT NULL DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
|
||||
remarks VARCHAR(500) -- 备注
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '消息表';
|
||||
|
||||
-- ============================================================================
|
||||
-- 4. Coze API调用记录表 (coze_api_call)
|
||||
-- ============================================================================
|
||||
CREATE TABLE coze_api_call (
|
||||
id VARCHAR(36) PRIMARY KEY, -- UUID主键
|
||||
conversation_id VARCHAR(36), -- 对话ID
|
||||
message_id VARCHAR(36), -- 消息ID
|
||||
-- Coze API 信息
|
||||
coze_chat_id VARCHAR(50), -- Coze聊天ID
|
||||
coze_conversation_id VARCHAR(50), -- Coze对话ID
|
||||
bot_id VARCHAR(50) NOT NULL, -- Bot ID
|
||||
workflow_id VARCHAR(50), -- Workflow ID
|
||||
user_id VARCHAR(36) NOT NULL, -- 用户ID
|
||||
-- 请求信息
|
||||
request_type VARCHAR(20) NOT NULL, -- 请求类型: chat/stream/retrieve/messages
|
||||
request_url VARCHAR(500), -- 请求URL
|
||||
request_body JSON, -- 请求体
|
||||
request_headers JSON, -- 请求头
|
||||
-- 响应信息
|
||||
response_status INT, -- HTTP状态码
|
||||
response_body JSON, -- 响应体
|
||||
response_headers JSON, -- 响应头
|
||||
-- 状态和时间
|
||||
status VARCHAR(20) NOT NULL, -- 调用状态: pending/success/failed/timeout
|
||||
start_time DATETIME NOT NULL, -- 开始时间
|
||||
end_time DATETIME, -- 结束时间
|
||||
duration_ms INT, -- 耗时(毫秒)
|
||||
-- 使用统计
|
||||
prompt_tokens INT DEFAULT 0, -- 输入Token数
|
||||
completion_tokens INT DEFAULT 0, -- 输出Token数
|
||||
total_tokens INT DEFAULT 0, -- 总Token数
|
||||
cost DECIMAL(10, 6) DEFAULT 0.000000, -- 费用
|
||||
-- 错误信息
|
||||
error_code VARCHAR(50), -- 错误代码
|
||||
error_message TEXT, -- 错误信息
|
||||
-- 公共字段
|
||||
create_by VARCHAR(36), -- 创建人ID
|
||||
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 创建时间
|
||||
update_by VARCHAR(36), -- 更新人ID
|
||||
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
|
||||
is_deleted TINYINT NOT NULL DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
|
||||
remarks VARCHAR(500) -- 备注
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'Coze API调用记录表';
|
||||
|
||||
-- ============================================================================
|
||||
-- 5. 情绪分析表 (emotion_analysis)
|
||||
-- ============================================================================
|
||||
CREATE TABLE emotion_analysis (
|
||||
id VARCHAR(36) PRIMARY KEY, -- UUID主键
|
||||
user_id VARCHAR(36) NOT NULL, -- 用户ID
|
||||
message_id VARCHAR(36), -- 关联消息ID
|
||||
text TEXT NOT NULL, -- 分析文本
|
||||
primary_emotion VARCHAR(50), -- 主要情绪
|
||||
intensity DECIMAL(3, 2), -- 情绪强度
|
||||
polarity VARCHAR(20), -- 情绪极性: positive-积极, negative-消极, neutral-中性
|
||||
confidence DECIMAL(3, 2), -- 置信度
|
||||
emotions JSON, -- 情绪分布详情
|
||||
keywords JSON, -- 关键词列表
|
||||
suggestion TEXT, -- 建议
|
||||
analysis_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 分析时间
|
||||
metadata JSON, -- 扩展元数据
|
||||
-- 公共字段
|
||||
create_by VARCHAR(36), -- 创建人ID
|
||||
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 创建时间
|
||||
update_by VARCHAR(36), -- 更新人ID
|
||||
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
|
||||
is_deleted TINYINT NOT NULL DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
|
||||
remarks VARCHAR(500) -- 备注
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '情绪分析表';
|
||||
|
||||
-- ============================================================================
|
||||
-- 6. 情绪记录表 (emotion_record)
|
||||
-- ============================================================================
|
||||
CREATE TABLE emotion_record (
|
||||
id VARCHAR(36) PRIMARY KEY, -- UUID主键
|
||||
user_id VARCHAR(36) NOT NULL, -- 用户ID
|
||||
record_date DATE NOT NULL, -- 记录日期
|
||||
emotion_type VARCHAR(50) NOT NULL, -- 情绪类型
|
||||
intensity DECIMAL(3, 2) NOT NULL, -- 情绪强度
|
||||
triggers TEXT, -- 触发因素
|
||||
description TEXT, -- 描述
|
||||
tags JSON, -- 标签
|
||||
weather VARCHAR(50), -- 天气
|
||||
location VARCHAR(100), -- 地点
|
||||
activity VARCHAR(100), -- 活动
|
||||
people VARCHAR(200), -- 相关人物
|
||||
notes TEXT, -- 备注
|
||||
-- 公共字段
|
||||
create_by VARCHAR(36), -- 创建人ID
|
||||
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 创建时间
|
||||
update_by VARCHAR(36), -- 更新人ID
|
||||
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
|
||||
is_deleted TINYINT NOT NULL DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
|
||||
remarks VARCHAR(500) -- 备注
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '情绪记录表';
|
||||
|
||||
-- ============================================================================
|
||||
-- 7. 成长课题表 (growth_topic)
|
||||
-- ============================================================================
|
||||
CREATE TABLE growth_topic (
|
||||
id VARCHAR(36) PRIMARY KEY, -- UUID主键
|
||||
title VARCHAR(100) NOT NULL, -- 课题标题
|
||||
category VARCHAR(50) NOT NULL, -- 分类
|
||||
difficulty VARCHAR(20) NOT NULL, -- 难度: easy-简单, medium-中等, hard-困难
|
||||
description TEXT, -- 描述
|
||||
content TEXT, -- 内容
|
||||
duration_days INT, -- 持续天数
|
||||
unlock_conditions JSON, -- 解锁条件
|
||||
is_unlocked TINYINT NOT NULL DEFAULT 1, -- 是否解锁
|
||||
progress DECIMAL(5, 2) NOT NULL DEFAULT 0.00, -- 进度百分比
|
||||
completed_time DATETIME, -- 完成时间
|
||||
rewards JSON, -- 奖励
|
||||
-- 公共字段
|
||||
create_by VARCHAR(36), -- 创建人ID
|
||||
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 创建时间
|
||||
update_by VARCHAR(36), -- 更新人ID
|
||||
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
|
||||
is_deleted TINYINT NOT NULL DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
|
||||
remarks VARCHAR(500) -- 备注
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '成长课题表';
|
||||
|
||||
-- ============================================================================
|
||||
-- 8. 课题互动表 (topic_interaction)
|
||||
-- ============================================================================
|
||||
CREATE TABLE topic_interaction (
|
||||
id VARCHAR(36) PRIMARY KEY, -- UUID主键
|
||||
topic_id VARCHAR(36) NOT NULL, -- 课题ID
|
||||
type VARCHAR(50) NOT NULL, -- 互动类型
|
||||
content TEXT, -- 内容
|
||||
user_input TEXT, -- 用户输入
|
||||
ai_response TEXT, -- AI回应
|
||||
rating INT, -- 评分
|
||||
feedback TEXT, -- 反馈
|
||||
completed_time DATETIME, -- 完成时间
|
||||
-- 公共字段
|
||||
create_by VARCHAR(36), -- 创建人ID
|
||||
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 创建时间
|
||||
update_by VARCHAR(36), -- 更新人ID
|
||||
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
|
||||
is_deleted TINYINT NOT NULL DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
|
||||
remarks VARCHAR(500) -- 备注
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '课题互动表';
|
||||
|
||||
-- ============================================================================
|
||||
-- 9. 地点标记表 (location_pin)
|
||||
-- ============================================================================
|
||||
CREATE TABLE location_pin (
|
||||
id VARCHAR(36) PRIMARY KEY, -- UUID主键
|
||||
name VARCHAR(100) NOT NULL, -- 地点名称
|
||||
type VARCHAR(50) NOT NULL, -- 地点类型
|
||||
category VARCHAR(50), -- 地点分类
|
||||
latitude DECIMAL(10, 8) NOT NULL, -- 纬度
|
||||
longitude DECIMAL(11, 8) NOT NULL, -- 经度
|
||||
address VARCHAR(200), -- 地址
|
||||
description TEXT, -- 描述
|
||||
created_by VARCHAR(36), -- 创建者
|
||||
likes INT NOT NULL DEFAULT 0, -- 点赞数
|
||||
visits INT NOT NULL DEFAULT 0, -- 访问数
|
||||
is_bookmarked TINYINT NOT NULL DEFAULT 0, -- 是否收藏
|
||||
last_visit_time DATETIME, -- 最后访问时间
|
||||
-- 公共字段
|
||||
create_by VARCHAR(36), -- 创建人ID
|
||||
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 创建时间
|
||||
update_by VARCHAR(36), -- 更新人ID
|
||||
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
|
||||
is_deleted TINYINT NOT NULL DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
|
||||
remarks VARCHAR(500) -- 备注
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '地点标记表';
|
||||
|
||||
-- ============================================================================
|
||||
-- 10. 社区帖子表 (community_post)
|
||||
-- ============================================================================
|
||||
CREATE TABLE community_post (
|
||||
id VARCHAR(36) PRIMARY KEY, -- UUID主键
|
||||
user_id VARCHAR(36) NOT NULL, -- 用户ID
|
||||
location_id VARCHAR(36), -- 地点ID
|
||||
title VARCHAR(200), -- 标题
|
||||
content TEXT NOT NULL, -- 内容
|
||||
type VARCHAR(50) NOT NULL, -- 帖子类型
|
||||
images JSON, -- 图片列表
|
||||
tags JSON, -- 标签
|
||||
likes INT NOT NULL DEFAULT 0, -- 点赞数
|
||||
view_count INT NOT NULL DEFAULT 0, -- 浏览数
|
||||
comment_count INT NOT NULL DEFAULT 0, -- 评论数
|
||||
is_private TINYINT NOT NULL DEFAULT 0, -- 是否私密
|
||||
-- 公共字段
|
||||
create_by VARCHAR(36), -- 创建人ID
|
||||
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 创建时间
|
||||
update_by VARCHAR(36), -- 更新人ID
|
||||
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
|
||||
is_deleted TINYINT NOT NULL DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
|
||||
remarks VARCHAR(500) -- 备注
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '社区帖子表';
|
||||
|
||||
-- ============================================================================
|
||||
-- 11. 评论表 (comment)
|
||||
-- ============================================================================
|
||||
CREATE TABLE comment (
|
||||
id VARCHAR(36) PRIMARY KEY, -- UUID主键
|
||||
post_id VARCHAR(36) NOT NULL, -- 帖子ID
|
||||
user_id VARCHAR(36) NOT NULL, -- 用户ID
|
||||
content TEXT NOT NULL, -- 评论内容
|
||||
reply_to_id VARCHAR(36), -- 回复的评论ID
|
||||
likes INT NOT NULL DEFAULT 0, -- 点赞数
|
||||
-- 公共字段
|
||||
create_by VARCHAR(36), -- 创建人ID
|
||||
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 创建时间
|
||||
update_by VARCHAR(36), -- 更新人ID
|
||||
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
|
||||
is_deleted TINYINT NOT NULL DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
|
||||
remarks VARCHAR(500) -- 备注
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '评论表';
|
||||
|
||||
-- ============================================================================
|
||||
-- 12. 成就表 (achievement)
|
||||
-- ============================================================================
|
||||
CREATE TABLE achievement (
|
||||
id VARCHAR(36) PRIMARY KEY, -- UUID主键
|
||||
title VARCHAR(100) NOT NULL, -- 成就标题
|
||||
description TEXT, -- 描述
|
||||
category VARCHAR(50) NOT NULL, -- 分类
|
||||
icon VARCHAR(200), -- 图标
|
||||
rarity VARCHAR(20) NOT NULL, -- 稀有度
|
||||
condition_type VARCHAR(50), -- 条件类型
|
||||
condition_value JSON, -- 条件值
|
||||
rewards JSON, -- 奖励
|
||||
unlocked_time DATETIME, -- 解锁时间
|
||||
progress DECIMAL(5, 2) NOT NULL DEFAULT 0.00, -- 进度
|
||||
is_hidden TINYINT NOT NULL DEFAULT 0, -- 是否隐藏
|
||||
-- 公共字段
|
||||
create_by VARCHAR(36), -- 创建人ID
|
||||
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 创建时间
|
||||
update_by VARCHAR(36), -- 更新人ID
|
||||
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
|
||||
is_deleted TINYINT NOT NULL DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
|
||||
remarks VARCHAR(500) -- 备注
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '成就表';
|
||||
|
||||
-- ============================================================================
|
||||
-- 13. 奖励表 (reward)
|
||||
-- ============================================================================
|
||||
CREATE TABLE reward (
|
||||
id VARCHAR(36) PRIMARY KEY, -- UUID主键
|
||||
topic_id VARCHAR(36), -- 课题ID
|
||||
achievement_id VARCHAR(36), -- 成就ID
|
||||
type VARCHAR(50) NOT NULL, -- 奖励类型
|
||||
name VARCHAR(100) NOT NULL, -- 奖励名称
|
||||
description TEXT, -- 描述
|
||||
icon VARCHAR(200), -- 图标
|
||||
rarity VARCHAR(20), -- 稀有度
|
||||
value JSON, -- 奖励值
|
||||
earned_time DATETIME, -- 获得时间
|
||||
is_new TINYINT NOT NULL DEFAULT 1, -- 是否新获得
|
||||
-- 公共字段
|
||||
create_by VARCHAR(36), -- 创建人ID
|
||||
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 创建时间
|
||||
update_by VARCHAR(36), -- 更新人ID
|
||||
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
|
||||
is_deleted TINYINT NOT NULL DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
|
||||
remarks VARCHAR(500) -- 备注
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '奖励表';
|
||||
|
||||
-- ============================================================================
|
||||
-- 14. 访客用户表 (guest_user)
|
||||
-- ============================================================================
|
||||
CREATE TABLE guest_user (
|
||||
id VARCHAR(36) PRIMARY KEY, -- UUID主键
|
||||
guest_user_id VARCHAR(50) NOT NULL UNIQUE, -- 访客用户ID (格式: guest_xxx)
|
||||
ip_address VARCHAR(45) NOT NULL, -- 客户端IP地址 (支持IPv6)
|
||||
user_agent TEXT, -- 用户代理信息
|
||||
nickname VARCHAR(50), -- 访客昵称
|
||||
avatar VARCHAR(500), -- 访客头像
|
||||
last_active_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 最后活跃时间
|
||||
conversation_count INT NOT NULL DEFAULT 0, -- 会话数量
|
||||
message_count INT NOT NULL DEFAULT 0, -- 消息数量
|
||||
location VARCHAR(100), -- IP地址的地理位置信息
|
||||
device_info VARCHAR(200), -- 设备信息
|
||||
-- 公共字段
|
||||
create_by VARCHAR(36), -- 创建人ID
|
||||
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 创建时间
|
||||
update_by VARCHAR(36), -- 更新人ID
|
||||
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
|
||||
is_deleted TINYINT NOT NULL DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
|
||||
remarks VARCHAR(500) -- 备注
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '访客用户表';
|
||||
|
||||
-- ============================================================================
|
||||
-- 15. 用户统计表 (user_stats)
|
||||
-- ============================================================================
|
||||
CREATE TABLE user_stats (
|
||||
id VARCHAR(36) PRIMARY KEY, -- UUID主键
|
||||
user_id VARCHAR(36) NOT NULL UNIQUE, -- 用户ID
|
||||
total_conversations INT NOT NULL DEFAULT 0, -- 总对话数
|
||||
total_messages INT NOT NULL DEFAULT 0, -- 总消息数
|
||||
total_emotions_recorded INT NOT NULL DEFAULT 0, -- 总情绪记录数
|
||||
topics_completed INT NOT NULL DEFAULT 0, -- 完成的课题数
|
||||
achievements_unlocked INT NOT NULL DEFAULT 0, -- 解锁的成就数
|
||||
total_points INT NOT NULL DEFAULT 0, -- 总积分
|
||||
consecutive_days INT NOT NULL DEFAULT 0, -- 连续使用天数
|
||||
max_consecutive_days INT NOT NULL DEFAULT 0, -- 最大连续天数
|
||||
locations_visited INT NOT NULL DEFAULT 0, -- 访问的地点数
|
||||
posts_created INT NOT NULL DEFAULT 0, -- 创建的帖子数
|
||||
comments_made INT NOT NULL DEFAULT 0, -- 评论数
|
||||
likes_received INT NOT NULL DEFAULT 0, -- 收到的点赞数
|
||||
social_interactions INT NOT NULL DEFAULT 0, -- 社交互动数
|
||||
-- 公共字段
|
||||
create_by VARCHAR(36), -- 创建人ID
|
||||
create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, -- 创建时间
|
||||
update_by VARCHAR(36), -- 更新人ID
|
||||
update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 更新时间
|
||||
is_deleted TINYINT NOT NULL DEFAULT 0, -- 是否删除: 0-未删除, 1-已删除
|
||||
remarks VARCHAR(500) -- 备注
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户统计表';
|
||||
|
||||
-- ============================================================================
|
||||
-- 创建索引以提高查询性能
|
||||
-- 注意: MySQL的CREATE INDEX不支持IF NOT EXISTS
|
||||
-- 如果索引已存在,重复执行会产生警告但不会中断脚本执行
|
||||
-- ============================================================================
|
||||
-- user表索引
|
||||
CREATE INDEX idx_user_account ON user (account);
|
||||
|
||||
CREATE INDEX idx_user_username ON user (username);
|
||||
|
||||
CREATE INDEX idx_user_email ON user (email);
|
||||
|
||||
CREATE INDEX idx_user_phone ON user (phone);
|
||||
|
||||
CREATE INDEX idx_user_last_active_time ON user (last_active_time);
|
||||
|
||||
CREATE INDEX idx_user_create_time ON user (create_time);
|
||||
|
||||
CREATE INDEX idx_user_member_level ON user (member_level);
|
||||
|
||||
CREATE INDEX idx_user_status ON user (status);
|
||||
|
||||
CREATE INDEX idx_user_is_verified ON user (is_verified);
|
||||
|
||||
CREATE INDEX idx_user_create_by ON user (create_by);
|
||||
|
||||
CREATE INDEX idx_user_update_by ON user (update_by);
|
||||
|
||||
CREATE INDEX idx_user_is_deleted ON user (is_deleted);
|
||||
|
||||
-- conversation表索引
|
||||
CREATE INDEX idx_conversation_user_id ON conversation (user_id);
|
||||
|
||||
CREATE INDEX idx_conversation_start_time ON conversation (start_time);
|
||||
|
||||
CREATE INDEX idx_conversation_user_id_start_time ON conversation (user_id, start_time);
|
||||
|
||||
CREATE INDEX idx_conversation_primary_emotion ON conversation (primary_emotion);
|
||||
|
||||
CREATE INDEX idx_conversation_end_time ON conversation (end_time);
|
||||
|
||||
CREATE INDEX idx_conversation_create_time ON conversation (create_time);
|
||||
|
||||
CREATE INDEX idx_conversation_coze_conversation_id ON conversation (coze_conversation_id);
|
||||
|
||||
CREATE INDEX idx_conversation_status ON conversation (status);
|
||||
|
||||
CREATE INDEX idx_conversation_last_active_time ON conversation (last_active_time);
|
||||
|
||||
CREATE INDEX idx_conversation_create_by ON conversation (create_by);
|
||||
|
||||
CREATE INDEX idx_conversation_update_by ON conversation (update_by);
|
||||
|
||||
CREATE INDEX idx_conversation_is_deleted ON conversation (is_deleted);
|
||||
|
||||
CREATE INDEX idx_conversation_user_type ON conversation (user_type);
|
||||
|
||||
CREATE INDEX idx_conversation_emotion_trend ON conversation (emotion_trend);
|
||||
|
||||
CREATE INDEX idx_conversation_confidence ON conversation (confidence);
|
||||
|
||||
CREATE INDEX idx_conversation_client_ip ON conversation (client_ip);
|
||||
|
||||
-- message表索引
|
||||
CREATE INDEX idx_message_conversation_id ON message (conversation_id);
|
||||
|
||||
CREATE INDEX idx_message_timestamp ON message (timestamp);
|
||||
|
||||
CREATE INDEX idx_message_conversation_id_timestamp ON message (conversation_id, timestamp);
|
||||
|
||||
CREATE INDEX idx_message_sender ON message (sender);
|
||||
|
||||
CREATE INDEX idx_message_type ON message (type);
|
||||
|
||||
CREATE INDEX idx_message_is_read ON message (is_read);
|
||||
|
||||
CREATE INDEX idx_message_create_time ON message (create_time);
|
||||
|
||||
CREATE INDEX idx_message_coze_chat_id ON message (coze_chat_id);
|
||||
|
||||
CREATE INDEX idx_message_status ON message (status);
|
||||
|
||||
CREATE INDEX idx_message_parent_message_id ON message (parent_message_id);
|
||||
|
||||
CREATE INDEX idx_message_create_by ON message (create_by);
|
||||
|
||||
CREATE INDEX idx_message_update_by ON message (update_by);
|
||||
|
||||
CREATE INDEX idx_message_is_deleted ON message (is_deleted);
|
||||
|
||||
-- coze_api_call表索引
|
||||
CREATE INDEX idx_coze_api_call_conversation_id ON coze_api_call (conversation_id);
|
||||
|
||||
CREATE INDEX idx_coze_api_call_message_id ON coze_api_call (message_id);
|
||||
|
||||
CREATE INDEX idx_coze_api_call_coze_chat_id ON coze_api_call (coze_chat_id);
|
||||
|
||||
CREATE INDEX idx_coze_api_call_bot_id ON coze_api_call (bot_id);
|
||||
|
||||
CREATE INDEX idx_coze_api_call_user_id ON coze_api_call (user_id);
|
||||
|
||||
CREATE INDEX idx_coze_api_call_status ON coze_api_call (status);
|
||||
|
||||
CREATE INDEX idx_coze_api_call_start_time ON coze_api_call (start_time);
|
||||
|
||||
-- emotion_analysis表索引
|
||||
CREATE INDEX idx_emotion_analysis_user_id ON emotion_analysis (user_id);
|
||||
|
||||
CREATE INDEX idx_emotion_analysis_message_id ON emotion_analysis (message_id);
|
||||
|
||||
CREATE INDEX idx_emotion_analysis_primary_emotion ON emotion_analysis (primary_emotion);
|
||||
|
||||
CREATE INDEX idx_emotion_analysis_analysis_time ON emotion_analysis (analysis_time);
|
||||
|
||||
CREATE INDEX idx_emotion_analysis_create_time ON emotion_analysis (create_time);
|
||||
|
||||
CREATE INDEX idx_emotion_analysis_create_by ON emotion_analysis (create_by);
|
||||
|
||||
CREATE INDEX idx_emotion_analysis_update_by ON emotion_analysis (update_by);
|
||||
|
||||
CREATE INDEX idx_emotion_analysis_is_deleted ON emotion_analysis (is_deleted);
|
||||
|
||||
-- emotion_record表索引
|
||||
CREATE INDEX idx_emotion_record_user_id ON emotion_record (user_id);
|
||||
|
||||
CREATE INDEX idx_emotion_record_date ON emotion_record (record_date);
|
||||
|
||||
CREATE INDEX idx_emotion_record_emotion_type ON emotion_record (emotion_type);
|
||||
|
||||
CREATE INDEX idx_emotion_record_user_id_date ON emotion_record (user_id, record_date);
|
||||
|
||||
CREATE INDEX idx_emotion_record_user_id_emotion_type ON emotion_record (user_id, emotion_type);
|
||||
|
||||
CREATE INDEX idx_emotion_record_intensity ON emotion_record (intensity);
|
||||
|
||||
CREATE INDEX idx_emotion_record_create_time ON emotion_record (create_time);
|
||||
|
||||
CREATE INDEX idx_emotion_record_create_by ON emotion_record (create_by);
|
||||
|
||||
CREATE INDEX idx_emotion_record_update_by ON emotion_record (update_by);
|
||||
|
||||
CREATE INDEX idx_emotion_record_is_deleted ON emotion_record (is_deleted);
|
||||
|
||||
-- growth_topic表索引
|
||||
CREATE INDEX idx_growth_topic_category ON growth_topic (category);
|
||||
|
||||
CREATE INDEX idx_growth_topic_difficulty ON growth_topic (difficulty);
|
||||
|
||||
CREATE INDEX idx_growth_topic_is_unlocked ON growth_topic (is_unlocked);
|
||||
|
||||
CREATE INDEX idx_growth_topic_progress ON growth_topic (progress);
|
||||
|
||||
CREATE INDEX idx_growth_topic_completed_time ON growth_topic (completed_time);
|
||||
|
||||
CREATE INDEX idx_growth_topic_category_difficulty ON growth_topic (category, difficulty);
|
||||
|
||||
CREATE INDEX idx_growth_topic_create_time ON growth_topic (create_time);
|
||||
|
||||
-- topic_interaction表索引
|
||||
CREATE INDEX idx_topic_interaction_topic_id ON topic_interaction (topic_id);
|
||||
|
||||
CREATE INDEX idx_topic_interaction_type ON topic_interaction (type);
|
||||
|
||||
CREATE INDEX idx_topic_interaction_completed_time ON topic_interaction (completed_time);
|
||||
|
||||
CREATE INDEX idx_topic_interaction_rating ON topic_interaction (rating);
|
||||
|
||||
CREATE INDEX idx_topic_interaction_topic_id_type ON topic_interaction (topic_id, type);
|
||||
|
||||
CREATE INDEX idx_topic_interaction_create_time ON topic_interaction (create_time);
|
||||
|
||||
-- location_pin表索引
|
||||
CREATE INDEX idx_location_pin_latitude_longitude ON location_pin (latitude, longitude);
|
||||
|
||||
CREATE INDEX idx_location_pin_type ON location_pin (type);
|
||||
|
||||
CREATE INDEX idx_location_pin_category ON location_pin (category);
|
||||
|
||||
CREATE INDEX idx_location_pin_created_by ON location_pin (created_by);
|
||||
|
||||
CREATE INDEX idx_location_pin_likes ON location_pin (likes);
|
||||
|
||||
CREATE INDEX idx_location_pin_visits ON location_pin (visits);
|
||||
|
||||
CREATE INDEX idx_location_pin_is_bookmarked ON location_pin (is_bookmarked);
|
||||
|
||||
CREATE INDEX idx_location_pin_type_category ON location_pin (type, category);
|
||||
|
||||
CREATE INDEX idx_location_pin_create_time ON location_pin (create_time);
|
||||
|
||||
CREATE INDEX idx_location_pin_last_visit_time ON location_pin (last_visit_time);
|
||||
|
||||
-- community_post表索引
|
||||
CREATE INDEX idx_community_post_user_id ON community_post (user_id);
|
||||
|
||||
CREATE INDEX idx_community_post_location_id ON community_post (location_id);
|
||||
|
||||
CREATE INDEX idx_community_post_create_time ON community_post (create_time);
|
||||
|
||||
CREATE INDEX idx_community_post_type ON community_post (type);
|
||||
|
||||
CREATE INDEX idx_community_post_likes ON community_post (likes);
|
||||
|
||||
CREATE INDEX idx_community_post_view_count ON community_post (view_count);
|
||||
|
||||
CREATE INDEX idx_community_post_is_private ON community_post (is_private);
|
||||
|
||||
CREATE INDEX idx_community_post_user_id_create_time ON community_post (user_id, create_time);
|
||||
|
||||
CREATE INDEX idx_community_post_type_create_time ON community_post (type, create_time);
|
||||
|
||||
-- comment表索引
|
||||
CREATE INDEX idx_comment_post_id ON comment (post_id);
|
||||
|
||||
CREATE INDEX idx_comment_user_id ON comment (user_id);
|
||||
|
||||
CREATE INDEX idx_comment_reply_to_id ON comment (reply_to_id);
|
||||
|
||||
CREATE INDEX idx_comment_create_time ON comment (create_time);
|
||||
|
||||
CREATE INDEX idx_comment_likes ON comment (likes);
|
||||
|
||||
CREATE INDEX idx_comment_post_id_create_time ON comment (post_id, create_time);
|
||||
|
||||
-- achievement表索引
|
||||
CREATE INDEX idx_achievement_category ON achievement (category);
|
||||
|
||||
CREATE INDEX idx_achievement_rarity ON achievement (rarity);
|
||||
|
||||
CREATE INDEX idx_achievement_unlocked_time ON achievement (unlocked_time);
|
||||
|
||||
CREATE INDEX idx_achievement_is_hidden ON achievement (is_hidden);
|
||||
|
||||
CREATE INDEX idx_achievement_progress ON achievement (progress);
|
||||
|
||||
CREATE INDEX idx_achievement_category_rarity ON achievement (category, rarity);
|
||||
|
||||
CREATE INDEX idx_achievement_create_time ON achievement (create_time);
|
||||
|
||||
-- reward表索引
|
||||
CREATE INDEX idx_reward_topic_id ON reward (topic_id);
|
||||
|
||||
CREATE INDEX idx_reward_achievement_id ON reward (achievement_id);
|
||||
|
||||
CREATE INDEX idx_reward_type ON reward (type);
|
||||
|
||||
CREATE INDEX idx_reward_earned_time ON reward (earned_time);
|
||||
|
||||
CREATE INDEX idx_reward_rarity ON reward (rarity);
|
||||
|
||||
CREATE INDEX idx_reward_is_new ON reward (is_new);
|
||||
|
||||
CREATE INDEX idx_reward_type_earned_time ON reward (type, earned_time);
|
||||
|
||||
CREATE INDEX idx_reward_create_time ON reward (create_time);
|
||||
|
||||
-- user_stats表索引
|
||||
CREATE INDEX idx_user_stats_user_id ON user_stats (user_id);
|
||||
|
||||
CREATE INDEX idx_user_stats_total_points ON user_stats (total_points);
|
||||
|
||||
CREATE INDEX idx_user_stats_consecutive_days ON user_stats (consecutive_days);
|
||||
|
||||
CREATE INDEX idx_user_stats_max_consecutive_days ON user_stats (max_consecutive_days);
|
||||
|
||||
CREATE INDEX idx_user_stats_social_interactions ON user_stats (social_interactions);
|
||||
|
||||
CREATE INDEX idx_user_stats_update_time ON user_stats (update_time);
|
||||
|
||||
CREATE INDEX idx_user_stats_create_time ON user_stats (create_time);
|
||||
|
||||
-- guest_user表索引
|
||||
CREATE INDEX idx_guest_user_guest_user_id ON guest_user (guest_user_id);
|
||||
|
||||
CREATE INDEX idx_guest_user_ip_address ON guest_user (ip_address);
|
||||
|
||||
CREATE INDEX idx_guest_user_last_active_time ON guest_user (last_active_time);
|
||||
|
||||
CREATE INDEX idx_guest_user_conversation_count ON guest_user (conversation_count);
|
||||
|
||||
CREATE INDEX idx_guest_user_message_count ON guest_user (message_count);
|
||||
|
||||
CREATE INDEX idx_guest_user_create_time ON guest_user (create_time);
|
||||
|
||||
CREATE INDEX idx_guest_user_create_by ON guest_user (create_by);
|
||||
|
||||
CREATE INDEX idx_guest_user_update_by ON guest_user (update_by);
|
||||
|
||||
CREATE INDEX idx_guest_user_is_deleted ON guest_user (is_deleted);
|
||||
|
||||
-- ============================================================================
|
||||
-- 数据库统计信息
|
||||
-- ============================================================================
|
||||
SELECT
|
||||
COUNT(*) as total_tables
|
||||
FROM
|
||||
INFORMATION_SCHEMA.TABLES
|
||||
WHERE
|
||||
TABLE_SCHEMA = 'emotion_museum';
|
||||
|
||||
-- 显示创建的表
|
||||
SELECT
|
||||
TABLE_NAME as table_name,
|
||||
TABLE_COMMENT as comment,
|
||||
ENGINE as engine
|
||||
FROM
|
||||
INFORMATION_SCHEMA.TABLES
|
||||
WHERE
|
||||
TABLE_SCHEMA = 'emotion_museum'
|
||||
ORDER BY
|
||||
TABLE_NAME;
|
||||
|
||||
-- 提交事务
|
||||
COMMIT;
|
||||
|
||||
-- 完成消息
|
||||
SELECT
|
||||
'Emotion Museum Database v3.0 Final (雪花算法主键版本) - 开发版本 deployment completed successfully!' as message,
|
||||
NOW () as completion_time,
|
||||
'All tables dropped and recreated with VARCHAR(36) primary keys. Development version - data will be lost on re-execution!' as description;
|
||||
@@ -0,0 +1,81 @@
|
||||
-- ============================================================================
|
||||
-- 数据库脚本验证查询
|
||||
-- 用于验证 mysql_emotion_museum_final.sql 执行后的表结构
|
||||
-- ============================================================================
|
||||
|
||||
-- 验证数据库是否存在
|
||||
SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = 'emotion_museum';
|
||||
|
||||
-- 验证所有表是否创建成功
|
||||
SELECT TABLE_NAME, TABLE_COMMENT
|
||||
FROM INFORMATION_SCHEMA.TABLES
|
||||
WHERE TABLE_SCHEMA = 'emotion_museum'
|
||||
ORDER BY TABLE_NAME;
|
||||
|
||||
-- 验证conversation表的字段结构(重点验证新增字段)
|
||||
SELECT
|
||||
COLUMN_NAME,
|
||||
DATA_TYPE,
|
||||
IS_NULLABLE,
|
||||
COLUMN_DEFAULT,
|
||||
COLUMN_COMMENT
|
||||
FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE TABLE_SCHEMA = 'emotion_museum'
|
||||
AND TABLE_NAME = 'conversation'
|
||||
ORDER BY ORDINAL_POSITION;
|
||||
|
||||
-- 验证conversation表的索引
|
||||
SELECT
|
||||
INDEX_NAME,
|
||||
COLUMN_NAME,
|
||||
NON_UNIQUE
|
||||
FROM INFORMATION_SCHEMA.STATISTICS
|
||||
WHERE TABLE_SCHEMA = 'emotion_museum'
|
||||
AND TABLE_NAME = 'conversation'
|
||||
ORDER BY INDEX_NAME, SEQ_IN_INDEX;
|
||||
|
||||
-- 验证新增字段是否存在
|
||||
SELECT
|
||||
CASE
|
||||
WHEN COUNT(*) = 9 THEN '✅ 所有新增字段都存在'
|
||||
ELSE CONCAT('❌ 缺少字段,只找到 ', COUNT(*), ' 个,应该是 9 个')
|
||||
END AS validation_result
|
||||
FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE TABLE_SCHEMA = 'emotion_museum'
|
||||
AND TABLE_NAME = 'conversation'
|
||||
AND COLUMN_NAME IN (
|
||||
'user_type', 'emotion_trend', 'keywords', 'ai_insights',
|
||||
'confidence', 'client_ip', 'user_agent', 'summary', 'tags'
|
||||
);
|
||||
|
||||
-- 验证新增索引是否存在
|
||||
SELECT
|
||||
CASE
|
||||
WHEN COUNT(*) = 4 THEN '✅ 所有新增索引都存在'
|
||||
ELSE CONCAT('❌ 缺少索引,只找到 ', COUNT(*), ' 个,应该是 4 个')
|
||||
END AS index_validation_result
|
||||
FROM INFORMATION_SCHEMA.STATISTICS
|
||||
WHERE TABLE_SCHEMA = 'emotion_museum'
|
||||
AND TABLE_NAME = 'conversation'
|
||||
AND INDEX_NAME IN (
|
||||
'idx_conversation_user_type',
|
||||
'idx_conversation_emotion_trend',
|
||||
'idx_conversation_confidence',
|
||||
'idx_conversation_client_ip'
|
||||
);
|
||||
|
||||
-- 统计总表数
|
||||
SELECT
|
||||
CASE
|
||||
WHEN COUNT(*) = 15 THEN '✅ 所有15个表都创建成功'
|
||||
ELSE CONCAT('❌ 表数量不正确,只有 ', COUNT(*), ' 个表,应该是 15 个')
|
||||
END AS table_count_result
|
||||
FROM INFORMATION_SCHEMA.TABLES
|
||||
WHERE TABLE_SCHEMA = 'emotion_museum';
|
||||
|
||||
-- 统计总索引数(conversation表)
|
||||
SELECT
|
||||
CONCAT('conversation表共有 ', COUNT(DISTINCT INDEX_NAME), ' 个索引') AS conversation_index_count
|
||||
FROM INFORMATION_SCHEMA.STATISTICS
|
||||
WHERE TABLE_SCHEMA = 'emotion_museum'
|
||||
AND TABLE_NAME = 'conversation';
|
||||
+257
@@ -0,0 +1,257 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 情绪博物馆容器部署脚本
|
||||
# 作者: EmotionMuseum Team
|
||||
# 版本: 1.0.0
|
||||
# 日期: 2025-07-13
|
||||
|
||||
set -e
|
||||
|
||||
# 颜色定义
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# 日志函数
|
||||
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_step() {
|
||||
echo -e "${BLUE}[STEP]${NC} $1"
|
||||
}
|
||||
|
||||
# 检查Docker和Docker Compose
|
||||
check_requirements() {
|
||||
log_step "检查系统要求..."
|
||||
|
||||
if ! command -v docker &> /dev/null; then
|
||||
log_error "Docker未安装,请先安装Docker"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v docker-compose &> /dev/null; then
|
||||
log_error "Docker Compose未安装,请先安装Docker Compose"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_info "Docker和Docker Compose检查通过"
|
||||
}
|
||||
|
||||
# 创建必要的目录
|
||||
create_directories() {
|
||||
log_step "创建部署目录..."
|
||||
|
||||
mkdir -p deploy/{mysql/conf.d,redis,nginx/{conf.d,ssl},logs}
|
||||
mkdir -p data/{mysql,redis,nacos}
|
||||
|
||||
log_info "目录创建完成"
|
||||
}
|
||||
|
||||
# 生成配置文件
|
||||
generate_configs() {
|
||||
log_step "生成配置文件..."
|
||||
|
||||
# MySQL配置
|
||||
if [ ! -f "deploy/mysql/conf.d/my.cnf" ]; then
|
||||
cat > deploy/mysql/conf.d/my.cnf << 'EOF'
|
||||
[mysqld]
|
||||
character-set-server=utf8mb4
|
||||
collation-server=utf8mb4_unicode_ci
|
||||
default-time-zone='+8:00'
|
||||
max_connections=1000
|
||||
max_allowed_packet=64M
|
||||
innodb_buffer_pool_size=512M
|
||||
innodb_log_file_size=256M
|
||||
slow_query_log=1
|
||||
slow_query_log_file=/var/log/mysql/slow.log
|
||||
long_query_time=2
|
||||
EOF
|
||||
log_info "MySQL配置文件已生成"
|
||||
fi
|
||||
|
||||
# Redis配置
|
||||
if [ ! -f "deploy/redis/redis.conf" ]; then
|
||||
cat > deploy/redis/redis.conf << 'EOF'
|
||||
bind 0.0.0.0
|
||||
port 6379
|
||||
timeout 300
|
||||
tcp-keepalive 60
|
||||
maxmemory 256mb
|
||||
maxmemory-policy allkeys-lru
|
||||
save 900 1
|
||||
save 300 10
|
||||
save 60 10000
|
||||
appendonly yes
|
||||
appendfsync everysec
|
||||
EOF
|
||||
log_info "Redis配置文件已生成"
|
||||
fi
|
||||
}
|
||||
|
||||
# 构建镜像
|
||||
build_images() {
|
||||
log_step "构建Docker镜像..."
|
||||
|
||||
log_info "构建后端服务镜像..."
|
||||
docker-compose build gateway ai-service user-service
|
||||
|
||||
log_info "构建前端应用镜像..."
|
||||
docker-compose build web
|
||||
|
||||
log_info "镜像构建完成"
|
||||
}
|
||||
|
||||
# 启动服务
|
||||
start_services() {
|
||||
log_step "启动服务..."
|
||||
|
||||
# 先启动基础服务
|
||||
log_info "启动基础服务 (MySQL, Redis, Nacos)..."
|
||||
docker-compose up -d mysql redis nacos
|
||||
|
||||
# 等待基础服务启动
|
||||
log_info "等待基础服务启动完成..."
|
||||
sleep 30
|
||||
|
||||
# 启动应用服务
|
||||
log_info "启动应用服务..."
|
||||
docker-compose up -d gateway ai-service user-service
|
||||
|
||||
# 等待应用服务启动
|
||||
log_info "等待应用服务启动完成..."
|
||||
sleep 20
|
||||
|
||||
# 启动前端和Nginx
|
||||
log_info "启动前端和Nginx..."
|
||||
docker-compose up -d web nginx
|
||||
|
||||
log_info "所有服务启动完成"
|
||||
}
|
||||
|
||||
# 检查服务状态
|
||||
check_services() {
|
||||
log_step "检查服务状态..."
|
||||
|
||||
echo ""
|
||||
docker-compose ps
|
||||
echo ""
|
||||
|
||||
# 检查关键服务健康状态
|
||||
log_info "检查服务健康状态..."
|
||||
|
||||
# 检查MySQL
|
||||
if docker-compose exec -T mysql mysqladmin ping -h localhost -u root -p123456 &> /dev/null; then
|
||||
log_info "✅ MySQL服务正常"
|
||||
else
|
||||
log_warn "❌ MySQL服务异常"
|
||||
fi
|
||||
|
||||
# 检查Redis
|
||||
if docker-compose exec -T redis redis-cli ping | grep -q PONG; then
|
||||
log_info "✅ Redis服务正常"
|
||||
else
|
||||
log_warn "❌ Redis服务异常"
|
||||
fi
|
||||
|
||||
# 检查Nacos
|
||||
if curl -s http://localhost:8848/nacos/v1/ns/operator/metrics &> /dev/null; then
|
||||
log_info "✅ Nacos服务正常"
|
||||
else
|
||||
log_warn "❌ Nacos服务异常"
|
||||
fi
|
||||
|
||||
# 检查网关
|
||||
if curl -s http://localhost:9000/actuator/health &> /dev/null; then
|
||||
log_info "✅ 网关服务正常"
|
||||
else
|
||||
log_warn "❌ 网关服务异常"
|
||||
fi
|
||||
}
|
||||
|
||||
# 显示访问信息
|
||||
show_access_info() {
|
||||
log_step "部署完成!"
|
||||
|
||||
echo ""
|
||||
echo "🎉 情绪博物馆部署成功!"
|
||||
echo ""
|
||||
echo "📱 访问地址:"
|
||||
echo " 前端应用: http://localhost"
|
||||
echo " API网关: http://localhost:9000"
|
||||
echo " Nacos: http://localhost:8848/nacos (用户名/密码: nacos/nacos)"
|
||||
echo ""
|
||||
echo "🔧 管理命令:"
|
||||
echo " 查看日志: docker-compose logs -f [服务名]"
|
||||
echo " 停止服务: docker-compose down"
|
||||
echo " 重启服务: docker-compose restart [服务名]"
|
||||
echo ""
|
||||
echo "📊 监控命令:"
|
||||
echo " 查看状态: docker-compose ps"
|
||||
echo " 查看资源: docker stats"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# 主函数
|
||||
main() {
|
||||
echo "🚀 开始部署情绪博物馆..."
|
||||
echo ""
|
||||
|
||||
check_requirements
|
||||
create_directories
|
||||
generate_configs
|
||||
build_images
|
||||
start_services
|
||||
|
||||
echo ""
|
||||
log_info "等待服务完全启动..."
|
||||
sleep 10
|
||||
|
||||
check_services
|
||||
show_access_info
|
||||
}
|
||||
|
||||
# 处理命令行参数
|
||||
case "${1:-}" in
|
||||
"build")
|
||||
log_info "仅构建镜像..."
|
||||
check_requirements
|
||||
create_directories
|
||||
generate_configs
|
||||
build_images
|
||||
;;
|
||||
"start")
|
||||
log_info "启动服务..."
|
||||
start_services
|
||||
check_services
|
||||
show_access_info
|
||||
;;
|
||||
"stop")
|
||||
log_info "停止服务..."
|
||||
docker-compose down
|
||||
;;
|
||||
"restart")
|
||||
log_info "重启服务..."
|
||||
docker-compose restart
|
||||
check_services
|
||||
;;
|
||||
"logs")
|
||||
docker-compose logs -f
|
||||
;;
|
||||
"status")
|
||||
check_services
|
||||
;;
|
||||
*)
|
||||
main
|
||||
;;
|
||||
esac
|
||||
+186
@@ -0,0 +1,186 @@
|
||||
# 情绪博物馆主站配置
|
||||
#
|
||||
# 部署方式说明:
|
||||
# 1. Docker Compose部署(推荐):使用容器服务名,如 emotion-gateway:9000, emotion-web:80
|
||||
# 2. 混合部署:Nginx在Docker中,服务在宿主机,使用 localhost:9000 或 host.docker.internal:9000
|
||||
# 3. 本地部署:Nginx在宿主机,使用 localhost:9000 或 127.0.0.1:9000
|
||||
#
|
||||
# 当前配置适用于:Docker Compose部署(所有服务都在Docker网络中)
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name localhost emotion-museum.com www.emotion-museum.com;
|
||||
|
||||
# 日志配置
|
||||
access_log /data/logs/nginx/nginx_access.log main;
|
||||
error_log /data/logs/nginx/nginx_error.log warn;
|
||||
|
||||
# 安全头
|
||||
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;
|
||||
|
||||
# API代理到网关服务 (Docker容器内部端口9000)
|
||||
location /api/ {
|
||||
# 限流
|
||||
limit_req zone=api burst=20 nodelay;
|
||||
|
||||
# 代理到网关服务 (Docker容器)
|
||||
proxy_pass http://emotion-gateway:9000;
|
||||
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;
|
||||
|
||||
# 超时设置
|
||||
proxy_connect_timeout 30s;
|
||||
proxy_send_timeout 30s;
|
||||
proxy_read_timeout 30s;
|
||||
|
||||
# 缓存控制
|
||||
proxy_cache_bypass $http_upgrade;
|
||||
proxy_no_cache $http_upgrade;
|
||||
|
||||
# WebSocket支持
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
}
|
||||
|
||||
# 前端静态文件服务 (代理到前端容器)
|
||||
location / {
|
||||
# 限流
|
||||
limit_req zone=web burst=50 nodelay;
|
||||
|
||||
# 代理到前端容器
|
||||
proxy_pass http://emotion-web:80;
|
||||
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;
|
||||
|
||||
# 超时设置
|
||||
proxy_connect_timeout 10s;
|
||||
proxy_send_timeout 10s;
|
||||
proxy_read_timeout 10s;
|
||||
}
|
||||
|
||||
# 静态资源缓存优化
|
||||
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
|
||||
proxy_pass http://emotion-web:80;
|
||||
expires 30d;
|
||||
add_header Cache-Control "public, immutable";
|
||||
add_header Vary "Accept-Encoding";
|
||||
}
|
||||
|
||||
# HTML文件不缓存
|
||||
location ~* \.(html|htm)$ {
|
||||
proxy_pass http://emotion-web:80;
|
||||
expires -1;
|
||||
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
||||
add_header Pragma "no-cache";
|
||||
}
|
||||
|
||||
# 健康检查
|
||||
location /nginx-health {
|
||||
access_log off;
|
||||
return 200 "healthy\n";
|
||||
add_header Content-Type text/plain;
|
||||
}
|
||||
|
||||
# 错误页面
|
||||
error_page 404 /404.html;
|
||||
error_page 500 502 503 504 /50x.html;
|
||||
|
||||
location = /50x.html {
|
||||
root /usr/share/nginx/html;
|
||||
}
|
||||
}
|
||||
|
||||
# HTTPS配置 (可选)
|
||||
# server {
|
||||
# listen 443 ssl http2;
|
||||
# server_name emotion-museum.com www.emotion-museum.com;
|
||||
#
|
||||
# # SSL证书配置
|
||||
# ssl_certificate /etc/nginx/ssl/emotion-museum.crt;
|
||||
# ssl_certificate_key /etc/nginx/ssl/emotion-museum.key;
|
||||
#
|
||||
# # SSL安全配置
|
||||
# ssl_protocols TLSv1.2 TLSv1.3;
|
||||
# ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384;
|
||||
# ssl_prefer_server_ciphers off;
|
||||
# ssl_session_cache shared:SSL:10m;
|
||||
# ssl_session_timeout 10m;
|
||||
#
|
||||
# # HSTS
|
||||
# add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
|
||||
#
|
||||
# # 其他配置与HTTP相同
|
||||
# include /etc/nginx/conf.d/emotion-museum-common.conf;
|
||||
# }
|
||||
|
||||
# HTTP重定向到HTTPS (可选)
|
||||
# server {
|
||||
# listen 80;
|
||||
# server_name emotion-museum.com www.emotion-museum.com;
|
||||
# return 301 https://$server_name$request_uri;
|
||||
# }
|
||||
|
||||
# ========================================
|
||||
# 备用配置:非Docker部署方式
|
||||
# ========================================
|
||||
# 如果不使用Docker Compose,而是直接在服务器上部署,
|
||||
# 请注释掉上面的配置,启用下面的配置
|
||||
|
||||
# server {
|
||||
# listen 80;
|
||||
# server_name localhost;
|
||||
#
|
||||
# # 日志配置
|
||||
# access_log /var/log/nginx/access.log;
|
||||
# error_log /var/log/nginx/error.log warn;
|
||||
#
|
||||
# # API代理到宿主机服务
|
||||
# location /api/ {
|
||||
# # 选择以下其中一种配置:
|
||||
#
|
||||
# # 方式1:使用localhost(推荐)
|
||||
# proxy_pass http://localhost:9000/;
|
||||
#
|
||||
# # 方式2:使用127.0.0.1
|
||||
# # proxy_pass http://127.0.0.1:9000/;
|
||||
#
|
||||
# # 方式3:使用服务器IP(替换为实际IP)
|
||||
# # proxy_pass http://192.168.1.100:9000/;
|
||||
#
|
||||
# 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;
|
||||
#
|
||||
# proxy_connect_timeout 30s;
|
||||
# proxy_send_timeout 30s;
|
||||
# proxy_read_timeout 30s;
|
||||
# }
|
||||
#
|
||||
# # 前端静态文件(直接从文件系统提供)
|
||||
# location / {
|
||||
# root /data/www/emotion-museum;
|
||||
# index index.html index.htm;
|
||||
# try_files $uri $uri/ /index.html;
|
||||
#
|
||||
# # 静态资源缓存
|
||||
# location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
|
||||
# root /data/www/emotion-museum;
|
||||
# expires 30d;
|
||||
# add_header Cache-Control "public, immutable";
|
||||
# }
|
||||
# }
|
||||
#
|
||||
# # 健康检查
|
||||
# location /health {
|
||||
# proxy_pass http://localhost:9000/actuator/health;
|
||||
# }
|
||||
# }
|
||||
@@ -0,0 +1,86 @@
|
||||
user nginx;
|
||||
worker_processes auto;
|
||||
error_log /var/log/nginx/error.log notice;
|
||||
pid /var/run/nginx.pid;
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
use epoll;
|
||||
multi_accept on;
|
||||
}
|
||||
|
||||
http {
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
# 日志格式
|
||||
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||
'$status $body_bytes_sent "$http_referer" '
|
||||
'"$http_user_agent" "$http_x_forwarded_for" '
|
||||
'$request_time $upstream_response_time';
|
||||
|
||||
access_log /var/log/nginx/access.log main;
|
||||
|
||||
# 基础配置
|
||||
sendfile on;
|
||||
tcp_nopush on;
|
||||
tcp_nodelay on;
|
||||
keepalive_timeout 65;
|
||||
types_hash_max_size 2048;
|
||||
server_tokens off;
|
||||
|
||||
# Gzip压缩
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
gzip_min_length 1024;
|
||||
gzip_proxied any;
|
||||
gzip_comp_level 6;
|
||||
gzip_types
|
||||
text/plain
|
||||
text/css
|
||||
text/xml
|
||||
text/javascript
|
||||
application/json
|
||||
application/javascript
|
||||
application/xml+rss
|
||||
application/atom+xml
|
||||
image/svg+xml;
|
||||
|
||||
# 客户端配置
|
||||
client_max_body_size 50M;
|
||||
client_body_buffer_size 128k;
|
||||
client_header_buffer_size 32k;
|
||||
large_client_header_buffers 4 32k;
|
||||
|
||||
# 代理配置
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_send_timeout 60s;
|
||||
proxy_read_timeout 60s;
|
||||
proxy_buffer_size 64k;
|
||||
proxy_buffers 4 64k;
|
||||
proxy_busy_buffers_size 128k;
|
||||
proxy_temp_file_write_size 128k;
|
||||
|
||||
# 上游服务器定义 - Docker容器服务
|
||||
upstream emotion-gateway {
|
||||
server emotion-gateway:9000 max_fails=3 fail_timeout=30s;
|
||||
keepalive 32;
|
||||
}
|
||||
|
||||
upstream emotion-ai {
|
||||
server emotion-ai:9002 max_fails=3 fail_timeout=30s;
|
||||
keepalive 32;
|
||||
}
|
||||
|
||||
upstream emotion-user {
|
||||
server emotion-user:9001 max_fails=3 fail_timeout=30s;
|
||||
keepalive 32;
|
||||
}
|
||||
|
||||
# 限流配置
|
||||
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
|
||||
limit_req_zone $binary_remote_addr zone=web:10m rate=20r/s;
|
||||
|
||||
# 包含站点配置
|
||||
include /etc/nginx/conf.d/*.conf;
|
||||
}
|
||||
@@ -0,0 +1,237 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
# MySQL数据库
|
||||
mysql:
|
||||
image: mysql:8.0
|
||||
container_name: emotion-mysql
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: 123456
|
||||
MYSQL_DATABASE: emotion_museum
|
||||
MYSQL_USER: emotion
|
||||
MYSQL_PASSWORD: emotion123
|
||||
TZ: Asia/Shanghai
|
||||
ports:
|
||||
- "3306:3306"
|
||||
volumes:
|
||||
- mysql_data:/var/lib/mysql
|
||||
- ./backend/mysql_emotion_museum_final.sql:/docker-entrypoint-initdb.d/init.sql
|
||||
- ./deploy/mysql/conf.d:/etc/mysql/conf.d
|
||||
- /data/logs/emotion-museum/mysql:/var/log/mysql
|
||||
command: --default-authentication-plugin=mysql_native_password
|
||||
networks:
|
||||
- emotion-network
|
||||
|
||||
# Redis缓存
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
container_name: emotion-redis
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "6379:6379"
|
||||
volumes:
|
||||
- redis_data:/data
|
||||
- ./deploy/redis/redis.conf:/usr/local/etc/redis/redis.conf
|
||||
- /data/logs/emotion-museum/redis:/var/log/redis
|
||||
command: redis-server /usr/local/etc/redis/redis.conf
|
||||
networks:
|
||||
- emotion-network
|
||||
|
||||
# Nacos注册中心
|
||||
nacos:
|
||||
image: nacos/nacos-server:v2.2.0
|
||||
container_name: emotion-nacos
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
MODE: standalone
|
||||
SPRING_DATASOURCE_PLATFORM: mysql
|
||||
MYSQL_SERVICE_HOST: mysql
|
||||
MYSQL_SERVICE_DB_NAME: nacos_config
|
||||
MYSQL_SERVICE_PORT: 3306
|
||||
MYSQL_SERVICE_USER: root
|
||||
MYSQL_SERVICE_PASSWORD: 123456
|
||||
MYSQL_SERVICE_DB_PARAM: characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true
|
||||
JVM_XMS: 512m
|
||||
JVM_XMX: 512m
|
||||
JVM_XMN: 256m
|
||||
ports:
|
||||
- "8848:8848"
|
||||
- "9848:9848"
|
||||
volumes:
|
||||
- nacos_data:/home/nacos/data
|
||||
- nacos_logs:/home/nacos/logs
|
||||
- /data/logs/emotion-museum/nacos:/home/nacos/logs
|
||||
depends_on:
|
||||
- mysql
|
||||
networks:
|
||||
- emotion-network
|
||||
|
||||
# 网关服务 - 使用宿主机JAR文件
|
||||
emotion-gateway:
|
||||
image: openjdk:17-jdk-alpine
|
||||
container_name: emotion-gateway
|
||||
restart: unless-stopped
|
||||
working_dir: /app
|
||||
command: >
|
||||
sh -c "
|
||||
apk add --no-cache curl tzdata &&
|
||||
cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime &&
|
||||
echo 'Asia/Shanghai' > /etc/timezone &&
|
||||
java -jar
|
||||
-Xms512m -Xmx1024m
|
||||
-Djava.security.egd=file:/dev/./urandom
|
||||
-Dspring.profiles.active=docker
|
||||
-Dlogging.file.path=/app/logs
|
||||
/app/emotion-gateway.jar
|
||||
"
|
||||
ports:
|
||||
- "9000:9000"
|
||||
environment:
|
||||
SPRING_PROFILES_ACTIVE: docker
|
||||
NACOS_SERVER_ADDR: nacos:8848
|
||||
MYSQL_HOST: mysql
|
||||
MYSQL_PORT: 3306
|
||||
REDIS_HOST: redis
|
||||
REDIS_PORT: 6379
|
||||
TZ: Asia/Shanghai
|
||||
volumes:
|
||||
- /data/builds/emotion-gateway.jar:/app/emotion-gateway.jar:ro
|
||||
- /data/logs/emotion-museum/gateway:/app/logs
|
||||
depends_on:
|
||||
- mysql
|
||||
- redis
|
||||
- nacos
|
||||
networks:
|
||||
- emotion-network
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:9000/actuator/health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 60s
|
||||
|
||||
# AI服务 - 使用宿主机JAR文件
|
||||
emotion-ai:
|
||||
image: openjdk:17-jdk-alpine
|
||||
container_name: emotion-ai
|
||||
restart: unless-stopped
|
||||
working_dir: /app
|
||||
command: >
|
||||
sh -c "
|
||||
apk add --no-cache curl tzdata &&
|
||||
cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime &&
|
||||
echo 'Asia/Shanghai' > /etc/timezone &&
|
||||
java -jar
|
||||
-Xms512m -Xmx1024m
|
||||
-Djava.security.egd=file:/dev/./urandom
|
||||
-Dspring.profiles.active=docker
|
||||
-Dlogging.file.path=/app/logs
|
||||
/app/emotion-ai.jar
|
||||
"
|
||||
ports:
|
||||
- "9002:9002"
|
||||
environment:
|
||||
SPRING_PROFILES_ACTIVE: docker
|
||||
NACOS_SERVER_ADDR: nacos:8848
|
||||
MYSQL_HOST: mysql
|
||||
MYSQL_PORT: 3306
|
||||
REDIS_HOST: redis
|
||||
REDIS_PORT: 6379
|
||||
COZE_API_TOKEN: ${COZE_API_TOKEN:-pat_GCR4qKzqpf90wMCvKsldMrB18KG3QsLDci65bZthssKsbLxu8X70BKYumleDcabO}
|
||||
TZ: Asia/Shanghai
|
||||
volumes:
|
||||
- /data/builds/emotion-ai.jar:/app/emotion-ai.jar:ro
|
||||
- /data/logs/emotion-museum/ai:/app/logs
|
||||
depends_on:
|
||||
- mysql
|
||||
- redis
|
||||
- nacos
|
||||
networks:
|
||||
- emotion-network
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:9002/actuator/health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 60s
|
||||
|
||||
# 用户服务 - 使用宿主机JAR文件
|
||||
emotion-user:
|
||||
image: openjdk:17-jdk-alpine
|
||||
container_name: emotion-user
|
||||
restart: unless-stopped
|
||||
working_dir: /app
|
||||
command: >
|
||||
sh -c "
|
||||
apk add --no-cache curl tzdata &&
|
||||
cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime &&
|
||||
echo 'Asia/Shanghai' > /etc/timezone &&
|
||||
java -jar
|
||||
-Xms512m -Xmx1024m
|
||||
-Djava.security.egd=file:/dev/./urandom
|
||||
-Dspring.profiles.active=docker
|
||||
-Dlogging.file.path=/app/logs
|
||||
/app/emotion-user.jar
|
||||
"
|
||||
ports:
|
||||
- "9001:9001"
|
||||
environment:
|
||||
SPRING_PROFILES_ACTIVE: docker
|
||||
NACOS_SERVER_ADDR: nacos:8848
|
||||
MYSQL_HOST: mysql
|
||||
MYSQL_PORT: 3306
|
||||
REDIS_HOST: redis
|
||||
REDIS_PORT: 6379
|
||||
TZ: Asia/Shanghai
|
||||
volumes:
|
||||
- /data/builds/emotion-user.jar:/app/emotion-user.jar:ro
|
||||
- /data/logs/emotion-museum/user:/app/logs
|
||||
depends_on:
|
||||
- mysql
|
||||
- redis
|
||||
- nacos
|
||||
networks:
|
||||
- emotion-network
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:9001/actuator/health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 60s
|
||||
|
||||
# Nginx反向代理
|
||||
nginx:
|
||||
image: nginx:alpine
|
||||
container_name: emotion-nginx
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
volumes:
|
||||
- ./deploy/nginx/nginx.conf:/etc/nginx/nginx.conf:ro
|
||||
- ./deploy/nginx/conf.d:/etc/nginx/conf.d:ro
|
||||
- ./deploy/nginx/ssl:/etc/nginx/ssl:ro
|
||||
- /data/www/emotion-museum:/data/www/emotion-museum:ro
|
||||
- /data/logs/emotion-museum/nginx:/var/log/nginx
|
||||
depends_on:
|
||||
- emotion-gateway
|
||||
- emotion-ai
|
||||
- emotion-user
|
||||
networks:
|
||||
- emotion-network
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost/nginx-health"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
|
||||
volumes:
|
||||
mysql_data:
|
||||
redis_data:
|
||||
nacos_data:
|
||||
nacos_logs:
|
||||
|
||||
networks:
|
||||
emotion-network:
|
||||
driver: bridge
|
||||
@@ -0,0 +1,253 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
# MySQL数据库
|
||||
mysql:
|
||||
image: mysql:8.0
|
||||
container_name: emotion-mysql-prod
|
||||
restart: always
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
|
||||
MYSQL_DATABASE: ${MYSQL_DATABASE}
|
||||
MYSQL_USER: ${MYSQL_USER}
|
||||
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
|
||||
TZ: ${TZ:-Asia/Shanghai}
|
||||
ports:
|
||||
- "3306:3306"
|
||||
volumes:
|
||||
- mysql_data:/var/lib/mysql
|
||||
- ./backend/mysql_emotion_museum_final.sql:/docker-entrypoint-initdb.d/init.sql
|
||||
- ./deploy/mysql/conf.d:/etc/mysql/conf.d
|
||||
- ./logs/mysql:/var/log/mysql
|
||||
command: --default-authentication-plugin=mysql_native_password
|
||||
networks:
|
||||
- emotion-network
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 1G
|
||||
reservations:
|
||||
memory: 512M
|
||||
|
||||
# Redis缓存
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
container_name: emotion-redis-prod
|
||||
restart: always
|
||||
ports:
|
||||
- "6379:6379"
|
||||
volumes:
|
||||
- redis_data:/data
|
||||
- ./deploy/redis/redis.conf:/usr/local/etc/redis/redis.conf
|
||||
- ./logs/redis:/var/log/redis
|
||||
command: redis-server /usr/local/etc/redis/redis.conf
|
||||
networks:
|
||||
- emotion-network
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 512M
|
||||
reservations:
|
||||
memory: 256M
|
||||
|
||||
# Nacos注册中心
|
||||
nacos:
|
||||
image: nacos/nacos-server:v2.2.0
|
||||
container_name: emotion-nacos-prod
|
||||
restart: always
|
||||
environment:
|
||||
MODE: standalone
|
||||
SPRING_DATASOURCE_PLATFORM: mysql
|
||||
MYSQL_SERVICE_HOST: mysql
|
||||
MYSQL_SERVICE_DB_NAME: nacos_config
|
||||
MYSQL_SERVICE_PORT: 3306
|
||||
MYSQL_SERVICE_USER: ${MYSQL_USER}
|
||||
MYSQL_SERVICE_PASSWORD: ${MYSQL_PASSWORD}
|
||||
MYSQL_SERVICE_DB_PARAM: characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true
|
||||
JVM_XMS: 512m
|
||||
JVM_XMX: 1024m
|
||||
JVM_XMN: 256m
|
||||
NACOS_AUTH_ENABLE: ${NACOS_AUTH_ENABLE:-false}
|
||||
ports:
|
||||
- "8848:8848"
|
||||
- "9848:9848"
|
||||
volumes:
|
||||
- nacos_data:/home/nacos/data
|
||||
- nacos_logs:/home/nacos/logs
|
||||
depends_on:
|
||||
- mysql
|
||||
networks:
|
||||
- emotion-network
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 1.5G
|
||||
reservations:
|
||||
memory: 512M
|
||||
|
||||
# 网关服务
|
||||
gateway:
|
||||
build:
|
||||
context: ./backend
|
||||
dockerfile: ./emotion-gateway/Dockerfile
|
||||
image: emotion-gateway:latest
|
||||
container_name: emotion-gateway-prod
|
||||
restart: always
|
||||
ports:
|
||||
- "9000:9000"
|
||||
environment:
|
||||
SPRING_PROFILES_ACTIVE: docker
|
||||
NACOS_SERVER_ADDR: nacos:8848
|
||||
MYSQL_HOST: mysql
|
||||
MYSQL_PORT: 3306
|
||||
REDIS_HOST: redis
|
||||
REDIS_PORT: 6379
|
||||
TZ: ${TZ:-Asia/Shanghai}
|
||||
volumes:
|
||||
- ./logs/gateway:/app/logs
|
||||
depends_on:
|
||||
- mysql
|
||||
- redis
|
||||
- nacos
|
||||
networks:
|
||||
- emotion-network
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 1G
|
||||
reservations:
|
||||
memory: 512M
|
||||
|
||||
# AI服务
|
||||
ai-service:
|
||||
build:
|
||||
context: ./backend
|
||||
dockerfile: ./emotion-ai/Dockerfile
|
||||
image: emotion-ai:latest
|
||||
container_name: emotion-ai-prod
|
||||
restart: always
|
||||
ports:
|
||||
- "9002:9002"
|
||||
environment:
|
||||
SPRING_PROFILES_ACTIVE: docker
|
||||
NACOS_SERVER_ADDR: nacos:8848
|
||||
MYSQL_HOST: mysql
|
||||
MYSQL_PORT: 3306
|
||||
REDIS_HOST: redis
|
||||
REDIS_PORT: 6379
|
||||
COZE_API_TOKEN: ${COZE_API_TOKEN}
|
||||
TZ: ${TZ:-Asia/Shanghai}
|
||||
volumes:
|
||||
- ./logs/ai:/app/logs
|
||||
depends_on:
|
||||
- mysql
|
||||
- redis
|
||||
- nacos
|
||||
networks:
|
||||
- emotion-network
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 1G
|
||||
reservations:
|
||||
memory: 512M
|
||||
|
||||
# 用户服务
|
||||
user-service:
|
||||
build:
|
||||
context: ./backend
|
||||
dockerfile: ./emotion-user/Dockerfile
|
||||
image: emotion-user:latest
|
||||
container_name: emotion-user-prod
|
||||
restart: always
|
||||
ports:
|
||||
- "9001:9001"
|
||||
environment:
|
||||
SPRING_PROFILES_ACTIVE: docker
|
||||
NACOS_SERVER_ADDR: nacos:8848
|
||||
MYSQL_HOST: mysql
|
||||
MYSQL_PORT: 3306
|
||||
REDIS_HOST: redis
|
||||
REDIS_PORT: 6379
|
||||
TZ: ${TZ:-Asia/Shanghai}
|
||||
volumes:
|
||||
- ./logs/user:/app/logs
|
||||
depends_on:
|
||||
- mysql
|
||||
- redis
|
||||
- nacos
|
||||
networks:
|
||||
- emotion-network
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 1G
|
||||
reservations:
|
||||
memory: 512M
|
||||
|
||||
# 前端应用
|
||||
web:
|
||||
build:
|
||||
context: ./web
|
||||
dockerfile: Dockerfile
|
||||
args:
|
||||
BUILD_ENV: production
|
||||
image: emotion-web:latest
|
||||
container_name: emotion-web-prod
|
||||
restart: always
|
||||
ports:
|
||||
- "3000:80"
|
||||
volumes:
|
||||
- ./logs/web:/var/log/nginx
|
||||
depends_on:
|
||||
- gateway
|
||||
networks:
|
||||
- emotion-network
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 256M
|
||||
reservations:
|
||||
memory: 128M
|
||||
|
||||
# Nginx反向代理
|
||||
nginx:
|
||||
image: nginx:alpine
|
||||
container_name: emotion-nginx-prod
|
||||
restart: always
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
volumes:
|
||||
- ./deploy/nginx/nginx.conf:/etc/nginx/nginx.conf
|
||||
- ./deploy/nginx/conf.d:/etc/nginx/conf.d
|
||||
- ./deploy/nginx/ssl:/etc/nginx/ssl
|
||||
- ./logs/nginx:/var/log/nginx
|
||||
depends_on:
|
||||
- web
|
||||
- gateway
|
||||
networks:
|
||||
- emotion-network
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 256M
|
||||
reservations:
|
||||
memory: 128M
|
||||
|
||||
volumes:
|
||||
mysql_data:
|
||||
driver: local
|
||||
redis_data:
|
||||
driver: local
|
||||
nacos_data:
|
||||
driver: local
|
||||
nacos_logs:
|
||||
driver: local
|
||||
|
||||
networks:
|
||||
emotion-network:
|
||||
driver: bridge
|
||||
ipam:
|
||||
config:
|
||||
- subnet: 172.20.0.0/16
|
||||
@@ -0,0 +1,178 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
# MySQL数据库
|
||||
mysql:
|
||||
image: mysql:8.0
|
||||
container_name: emotion-mysql
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: 123456
|
||||
MYSQL_DATABASE: emotion_museum
|
||||
MYSQL_USER: emotion
|
||||
MYSQL_PASSWORD: emotion123
|
||||
TZ: Asia/Shanghai
|
||||
ports:
|
||||
- "3306:3306"
|
||||
volumes:
|
||||
- mysql_data:/var/lib/mysql
|
||||
- ./backend/mysql_emotion_museum_final.sql:/docker-entrypoint-initdb.d/init.sql
|
||||
- ./deploy/mysql/conf.d:/etc/mysql/conf.d
|
||||
command: --default-authentication-plugin=mysql_native_password
|
||||
networks:
|
||||
- emotion-network
|
||||
|
||||
# Redis缓存
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
container_name: emotion-redis
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "6379:6379"
|
||||
volumes:
|
||||
- redis_data:/data
|
||||
- ./deploy/redis/redis.conf:/usr/local/etc/redis/redis.conf
|
||||
command: redis-server /usr/local/etc/redis/redis.conf
|
||||
networks:
|
||||
- emotion-network
|
||||
|
||||
# Nacos注册中心
|
||||
nacos:
|
||||
image: nacos/nacos-server:v2.2.0
|
||||
container_name: emotion-nacos
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
MODE: standalone
|
||||
SPRING_DATASOURCE_PLATFORM: mysql
|
||||
MYSQL_SERVICE_HOST: mysql
|
||||
MYSQL_SERVICE_DB_NAME: nacos_config
|
||||
MYSQL_SERVICE_PORT: 3306
|
||||
MYSQL_SERVICE_USER: root
|
||||
MYSQL_SERVICE_PASSWORD: 123456
|
||||
MYSQL_SERVICE_DB_PARAM: characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useSSL=false&allowPublicKeyRetrieval=true
|
||||
JVM_XMS: 512m
|
||||
JVM_XMX: 512m
|
||||
JVM_XMN: 256m
|
||||
ports:
|
||||
- "8848:8848"
|
||||
- "9848:9848"
|
||||
volumes:
|
||||
- nacos_data:/home/nacos/data
|
||||
- nacos_logs:/home/nacos/logs
|
||||
depends_on:
|
||||
- mysql
|
||||
networks:
|
||||
- emotion-network
|
||||
|
||||
# 网关服务
|
||||
gateway:
|
||||
build:
|
||||
context: ./backend
|
||||
dockerfile: ./emotion-gateway/Dockerfile
|
||||
container_name: emotion-gateway
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "9000:9000"
|
||||
environment:
|
||||
SPRING_PROFILES_ACTIVE: docker
|
||||
NACOS_SERVER_ADDR: nacos:8848
|
||||
MYSQL_HOST: mysql
|
||||
MYSQL_PORT: 3306
|
||||
REDIS_HOST: redis
|
||||
REDIS_PORT: 6379
|
||||
depends_on:
|
||||
- mysql
|
||||
- redis
|
||||
- nacos
|
||||
networks:
|
||||
- emotion-network
|
||||
|
||||
# AI服务
|
||||
ai-service:
|
||||
build:
|
||||
context: ./backend
|
||||
dockerfile: ./emotion-ai/Dockerfile
|
||||
container_name: emotion-ai
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "9002:9002"
|
||||
environment:
|
||||
SPRING_PROFILES_ACTIVE: docker
|
||||
NACOS_SERVER_ADDR: nacos:8848
|
||||
MYSQL_HOST: mysql
|
||||
MYSQL_PORT: 3306
|
||||
REDIS_HOST: redis
|
||||
REDIS_PORT: 6379
|
||||
depends_on:
|
||||
- mysql
|
||||
- redis
|
||||
- nacos
|
||||
networks:
|
||||
- emotion-network
|
||||
|
||||
# 用户服务
|
||||
user-service:
|
||||
build:
|
||||
context: ./backend
|
||||
dockerfile: ./emotion-user/Dockerfile
|
||||
container_name: emotion-user
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "9001:9001"
|
||||
environment:
|
||||
SPRING_PROFILES_ACTIVE: docker
|
||||
NACOS_SERVER_ADDR: nacos:8848
|
||||
MYSQL_HOST: mysql
|
||||
MYSQL_PORT: 3306
|
||||
REDIS_HOST: redis
|
||||
REDIS_PORT: 6379
|
||||
depends_on:
|
||||
- mysql
|
||||
- redis
|
||||
- nacos
|
||||
networks:
|
||||
- emotion-network
|
||||
|
||||
# 前端应用
|
||||
web:
|
||||
build:
|
||||
context: ./web
|
||||
dockerfile: Dockerfile
|
||||
container_name: emotion-web
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "3000:80"
|
||||
depends_on:
|
||||
- gateway
|
||||
networks:
|
||||
- emotion-network
|
||||
|
||||
# Nginx反向代理
|
||||
nginx:
|
||||
image: nginx:alpine
|
||||
container_name: emotion-nginx
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
volumes:
|
||||
- ./deploy/nginx/nginx.conf:/etc/nginx/nginx.conf
|
||||
- ./deploy/nginx/conf.d:/etc/nginx/conf.d
|
||||
- ./deploy/nginx/ssl:/etc/nginx/ssl
|
||||
- nginx_logs:/var/log/nginx
|
||||
depends_on:
|
||||
- web
|
||||
- gateway
|
||||
networks:
|
||||
- emotion-network
|
||||
|
||||
volumes:
|
||||
mysql_data:
|
||||
redis_data:
|
||||
nacos_data:
|
||||
nacos_logs:
|
||||
nginx_logs:
|
||||
|
||||
networks:
|
||||
emotion-network:
|
||||
driver: bridge
|
||||
@@ -0,0 +1,10 @@
|
||||
# 基础环境变量配置
|
||||
VITE_APP_TITLE=情绪博物馆
|
||||
VITE_APP_VERSION=1.0.0
|
||||
|
||||
# API配置
|
||||
VITE_API_BASE_URL=/api
|
||||
VITE_API_TIMEOUT=30000
|
||||
|
||||
# 开发环境配置
|
||||
VITE_APP_ENV=development
|
||||
@@ -0,0 +1,12 @@
|
||||
# 开发环境配置
|
||||
VITE_APP_ENV=development
|
||||
VITE_APP_TITLE=情绪博物馆(开发环境)
|
||||
|
||||
# 开发环境API配置
|
||||
VITE_API_BASE_URL=/api
|
||||
VITE_API_TARGET=http://localhost:9000
|
||||
VITE_API_TIMEOUT=30000
|
||||
|
||||
# 开发环境特殊配置
|
||||
VITE_DEBUG_MODE=true
|
||||
VITE_MOCK_DATA=false
|
||||
@@ -0,0 +1,13 @@
|
||||
# Docker环境配置
|
||||
VITE_APP_TITLE=情绪博物馆
|
||||
VITE_APP_VERSION=1.0.0
|
||||
VITE_APP_ENV=docker
|
||||
|
||||
# API配置
|
||||
VITE_API_BASE_URL=/api
|
||||
VITE_API_TARGET=http://gateway:9000
|
||||
VITE_API_TIMEOUT=30000
|
||||
|
||||
# 功能开关
|
||||
VITE_DEBUG_MODE=false
|
||||
VITE_MOCK_DATA=false
|
||||
@@ -0,0 +1,12 @@
|
||||
# 生产环境配置
|
||||
VITE_APP_ENV=production
|
||||
VITE_APP_TITLE=情绪博物馆
|
||||
|
||||
# 生产环境API配置
|
||||
VITE_API_BASE_URL=https://api.emotion-museum.com/api
|
||||
VITE_API_TARGET=https://api.emotion-museum.com
|
||||
VITE_API_TIMEOUT=30000
|
||||
|
||||
# 生产环境特殊配置
|
||||
VITE_DEBUG_MODE=false
|
||||
VITE_MOCK_DATA=false
|
||||
@@ -0,0 +1,12 @@
|
||||
# 测试环境配置
|
||||
VITE_APP_ENV=test
|
||||
VITE_APP_TITLE=情绪博物馆(测试环境)
|
||||
|
||||
# 测试环境API配置
|
||||
VITE_API_BASE_URL=https://test-api.emotion-museum.com/api
|
||||
VITE_API_TARGET=https://test-api.emotion-museum.com
|
||||
VITE_API_TIMEOUT=30000
|
||||
|
||||
# 测试环境特殊配置
|
||||
VITE_DEBUG_MODE=true
|
||||
VITE_MOCK_DATA=false
|
||||
@@ -0,0 +1,55 @@
|
||||
# 前端应用Dockerfile
|
||||
# 构建阶段
|
||||
FROM node:18-alpine AS builder
|
||||
|
||||
# 设置工作目录
|
||||
WORKDIR /app
|
||||
|
||||
# 设置npm镜像源
|
||||
RUN npm config set registry https://registry.npmmirror.com
|
||||
|
||||
# 复制package文件
|
||||
COPY package*.json ./
|
||||
|
||||
# 安装依赖
|
||||
RUN npm ci --only=production
|
||||
|
||||
# 复制源代码
|
||||
COPY . .
|
||||
|
||||
# 构建应用
|
||||
RUN npm run build
|
||||
|
||||
# 生产阶段
|
||||
FROM nginx:alpine
|
||||
|
||||
# 安装必要工具
|
||||
RUN apk add --no-cache curl tzdata && \
|
||||
cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
|
||||
echo "Asia/Shanghai" > /etc/timezone
|
||||
|
||||
# 复制构建产物
|
||||
COPY --from=builder /app/dist /usr/share/nginx/html
|
||||
|
||||
# 复制nginx配置
|
||||
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
||||
|
||||
# 创建nginx用户
|
||||
RUN addgroup -g 101 -S nginx && \
|
||||
adduser -S -D -H -u 101 -h /var/cache/nginx -s /sbin/nologin -G nginx -g nginx nginx
|
||||
|
||||
# 设置权限
|
||||
RUN chown -R nginx:nginx /usr/share/nginx/html && \
|
||||
chown -R nginx:nginx /var/cache/nginx && \
|
||||
chown -R nginx:nginx /var/log/nginx && \
|
||||
chown -R nginx:nginx /etc/nginx/conf.d
|
||||
|
||||
# 健康检查
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=3 \
|
||||
CMD curl -f http://localhost:80/ || exit 1
|
||||
|
||||
# 暴露端口
|
||||
EXPOSE 80
|
||||
|
||||
# 启动nginx
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
+1
@@ -0,0 +1 @@
|
||||
.analysis-simple[data-v-28c071bd]{min-height:100vh;background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);padding:20px}.analysis-simple .page-header[data-v-28c071bd]{display:flex;justify-content:space-between;align-items:center;background:rgba(255,255,255,.1);padding:20px;border-radius:12px;margin-bottom:20px}.analysis-simple .page-header h1[data-v-28c071bd]{color:#fff;margin:0}.analysis-simple .page-content[data-v-28c071bd]{background:rgba(255,255,255,.95);padding:40px;border-radius:12px;text-align:center}.analysis-simple .page-content .welcome-message h2[data-v-28c071bd]{color:#333;margin-bottom:16px}.analysis-simple .page-content .welcome-message p[data-v-28c071bd]{color:#666;margin-bottom:32px;font-size:16px}.analysis-simple .page-content .welcome-message .test-buttons[data-v-28c071bd]{display:flex;gap:16px;justify-content:center;flex-wrap:wrap}
|
||||
+1
File diff suppressed because one or more lines are too long
+1
@@ -0,0 +1 @@
|
||||
.history-simple[data-v-4baa7231]{min-height:100vh;background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);padding:20px}.history-simple .page-header[data-v-4baa7231]{display:flex;justify-content:space-between;align-items:center;background:rgba(255,255,255,.1);padding:20px;border-radius:12px;margin-bottom:20px}.history-simple .page-header h1[data-v-4baa7231]{color:#fff;margin:0}.history-simple .page-content[data-v-4baa7231]{background:rgba(255,255,255,.95);padding:40px;border-radius:12px;text-align:center}.history-simple .page-content .welcome-message h2[data-v-4baa7231]{color:#333;margin-bottom:16px}.history-simple .page-content .welcome-message p[data-v-4baa7231]{color:#666;margin-bottom:32px;font-size:16px}.history-simple .page-content .welcome-message .test-buttons[data-v-4baa7231]{display:flex;gap:16px;justify-content:center;flex-wrap:wrap}
|
||||
File diff suppressed because one or more lines are too long
+1
@@ -0,0 +1 @@
|
||||
.home-test[data-v-6c328404]{min-height:100vh;background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);padding:40px;text-align:center;color:#fff}h1[data-v-6c328404]{font-size:2.5rem;margin-bottom:20px;text-shadow:2px 2px 4px rgba(0,0,0,.3)}p[data-v-6c328404]{font-size:1.2rem;margin-bottom:30px}.test-buttons[data-v-6c328404]{display:flex;gap:20px;justify-content:center;flex-wrap:wrap;margin-bottom:40px}.test-btn[data-v-6c328404]{padding:12px 24px;font-size:16px;background:rgba(255,255,255,.2);border:2px solid rgba(255,255,255,.3);border-radius:8px;color:#fff;cursor:pointer;transition:all .3s ease}.test-btn[data-v-6c328404]:hover{background:rgba(255,255,255,.3);border-color:#ffffff80;transform:translateY(-2px)}.info[data-v-6c328404]{background:rgba(255,255,255,.1);padding:20px;border-radius:12px;max-width:400px;margin:0 auto}.info p[data-v-6c328404]{margin:10px 0;font-size:1rem}
|
||||
File diff suppressed because one or more lines are too long
+1
@@ -0,0 +1 @@
|
||||
import{_ as d,u as p,b as m,o as v,e as f,f as t,c as o,w as n,g as l}from"./index-bf5be19f.js";const y={class:"analysis-simple"},k={class:"page-header"},b={class:"page-content"},g={class:"welcome-message"},C={class:"test-buttons"},c={__name:"AnalysisSimple",setup(x){const a=p(),_=()=>{a.push("/")},r=()=>{alert("情绪分析页面测试按钮工作正常!")};return(i,s)=>{const e=m("a-button");return v(),f("div",y,[t("div",k,[s[3]||(s[3]=t("h1",null,"情绪分析",-1)),o(e,{onClick:_},{default:n(()=>s[2]||(s[2]=[l("返回首页")])),_:1,__:[2]})]),t("div",b,[t("div",g,[s[7]||(s[7]=t("h2",null,"情绪分析功能",-1)),s[8]||(s[8]=t("p",null,"这里将提供强大的情绪分析功能,帮助您了解自己的情绪状态。",-1)),t("div",C,[o(e,{type:"primary",onClick:r},{default:n(()=>s[4]||(s[4]=[l("测试按钮")])),_:1,__:[4]}),o(e,{onClick:s[0]||(s[0]=u=>i.$router.push("/chat"))},{default:n(()=>s[5]||(s[5]=[l("开始对话")])),_:1,__:[5]}),o(e,{onClick:s[1]||(s[1]=u=>i.$router.push("/history"))},{default:n(()=>s[6]||(s[6]=[l("查看历史")])),_:1,__:[6]})])])])])}}},$=d(c,[["__scopeId","data-v-28c071bd"]]);export{$ as default};
|
||||
+1
File diff suppressed because one or more lines are too long
+1
@@ -0,0 +1 @@
|
||||
import{_ as p,u as d,b as m,o as v,e as f,f as s,c as e,w as n,g as l}from"./index-bf5be19f.js";const y={class:"history-simple"},k={class:"page-header"},b={class:"page-content"},g={class:"welcome-message"},C={class:"test-buttons"},x={__name:"HistorySimple",setup(B){const i=d(),r=()=>{i.push("/")},_=()=>{alert("历史记录页面测试按钮工作正常!")};return(a,t)=>{const o=m("a-button");return v(),f("div",y,[s("div",k,[t[3]||(t[3]=s("h1",null,"对话历史",-1)),e(o,{onClick:r},{default:n(()=>t[2]||(t[2]=[l("返回首页")])),_:1,__:[2]})]),s("div",b,[s("div",g,[t[7]||(t[7]=s("h2",null,"对话历史记录",-1)),t[8]||(t[8]=s("p",null,"这里将显示您的所有对话历史记录。",-1)),s("div",C,[e(o,{type:"primary",onClick:_},{default:n(()=>t[4]||(t[4]=[l("测试按钮")])),_:1,__:[4]}),e(o,{onClick:t[0]||(t[0]=u=>a.$router.push("/chat"))},{default:n(()=>t[5]||(t[5]=[l("开始对话")])),_:1,__:[5]}),e(o,{onClick:t[1]||(t[1]=u=>a.$router.push("/analysis"))},{default:n(()=>t[6]||(t[6]=[l("情绪分析")])),_:1,__:[6]})])])])])}}},c=p(x,[["__scopeId","data-v-4baa7231"]]);export{c as default};
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
import{_ as r,u as i,a as _,k as p,o as d,e as m,f as t,t as b}from"./index-bf5be19f.js";const v={class:"home-test"},T={class:"info"},f={__name:"HomeTest",setup(g){const o=i(),e=_(""),n=()=>{e.value=new Date().toLocaleString()},l=()=>{alert("测试按钮工作正常!Vue应用运行正常!")},a=()=>{o.push("/chat")},u=()=>{o.push("/history")},c=()=>{o.push("/analysis")};return p(()=>{n(),setInterval(n,1e3),console.log("HomeTest页面加载成功")}),(k,s)=>(d(),m("div",v,[s[1]||(s[1]=t("h1",null,"情绪博物馆测试页面",-1)),s[2]||(s[2]=t("p",null,"如果您能看到这个页面,说明Vue应用正在正常工作!",-1)),t("div",{class:"test-buttons"},[t("button",{onClick:l,class:"test-btn"},"测试按钮1"),t("button",{onClick:a,class:"test-btn"},"前往聊天页面"),t("button",{onClick:u,class:"test-btn"},"前往历史页面"),t("button",{onClick:c,class:"test-btn"},"前往分析页面")]),t("div",T,[t("p",null,"当前时间: "+b(e.value),1),s[0]||(s[0]=t("p",null,"页面加载状态: 正常",-1))])]))}},h=r(f,[["__scopeId","data-v-6c328404"]]);export{h as default};
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,56 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>情绪博物馆 - AI心理健康助手</title>
|
||||
<meta name="description" content="情绪博物馆 - 您的专属AI心理健康助手,提供情绪分析、心理支持和个性化建议" />
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'Helvetica Neue', Helvetica, Arial, sans-serif;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
#app {
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.loading {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
color: white;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.loading::after {
|
||||
content: '';
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border: 2px solid transparent;
|
||||
border-top: 2px solid white;
|
||||
border-radius: 50%;
|
||||
animation: spin 1s linear infinite;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
</style>
|
||||
<script type="module" crossorigin src="/assets/js/index-bf5be19f.js"></script>
|
||||
<link rel="stylesheet" href="/assets/css/index-4213a94d.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app">
|
||||
<div class="loading">加载中...</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,64 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name localhost;
|
||||
root /usr/share/nginx/html;
|
||||
index index.html index.htm;
|
||||
|
||||
# Gzip压缩
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
gzip_min_length 1024;
|
||||
gzip_comp_level 6;
|
||||
gzip_types
|
||||
text/plain
|
||||
text/css
|
||||
text/xml
|
||||
text/javascript
|
||||
application/json
|
||||
application/javascript
|
||||
application/xml+rss
|
||||
application/atom+xml
|
||||
image/svg+xml;
|
||||
|
||||
# 静态资源缓存
|
||||
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
|
||||
expires 1y;
|
||||
add_header Cache-Control "public, immutable";
|
||||
add_header Vary "Accept-Encoding";
|
||||
try_files $uri =404;
|
||||
}
|
||||
|
||||
# HTML文件不缓存
|
||||
location ~* \.(html|htm)$ {
|
||||
expires -1;
|
||||
add_header Cache-Control "no-cache, no-store, must-revalidate";
|
||||
add_header Pragma "no-cache";
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
||||
# SPA路由支持
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
|
||||
# 安全头
|
||||
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;
|
||||
}
|
||||
|
||||
# 健康检查
|
||||
location /health {
|
||||
access_log off;
|
||||
return 200 "healthy\n";
|
||||
add_header Content-Type text/plain;
|
||||
}
|
||||
|
||||
# 错误页面
|
||||
error_page 404 /index.html;
|
||||
error_page 500 502 503 504 /50x.html;
|
||||
|
||||
location = /50x.html {
|
||||
root /usr/share/nginx/html;
|
||||
}
|
||||
}
|
||||
+412
@@ -0,0 +1,412 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 情绪博物馆管理脚本
|
||||
# 提供服务管理、监控、备份等功能
|
||||
|
||||
set -e
|
||||
|
||||
# 颜色定义
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
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_step() {
|
||||
echo -e "${BLUE}[STEP]${NC} $1"
|
||||
}
|
||||
|
||||
# 显示帮助信息
|
||||
show_help() {
|
||||
echo "情绪博物馆管理脚本"
|
||||
echo ""
|
||||
echo "用法: $0 [命令] [选项]"
|
||||
echo ""
|
||||
echo "命令:"
|
||||
echo " start 启动所有服务"
|
||||
echo " stop 停止所有服务"
|
||||
echo " restart 重启所有服务"
|
||||
echo " status 查看服务状态"
|
||||
echo " logs 查看服务日志"
|
||||
echo " backup 备份数据"
|
||||
echo " restore 恢复数据"
|
||||
echo " update 更新服务"
|
||||
echo " clean 清理资源"
|
||||
echo " monitor 监控服务"
|
||||
echo " health 健康检查"
|
||||
echo ""
|
||||
echo "选项:"
|
||||
echo " -f, --follow 跟踪日志输出"
|
||||
echo " -s, --service 指定服务名称"
|
||||
echo " -h, --help 显示帮助信息"
|
||||
echo ""
|
||||
echo "示例:"
|
||||
echo " $0 start # 启动所有服务"
|
||||
echo " $0 logs -f # 跟踪所有服务日志"
|
||||
echo " $0 logs -s gateway # 查看网关服务日志"
|
||||
echo " $0 restart -s ai-service # 重启AI服务"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# 启动服务
|
||||
start_services() {
|
||||
log_step "启动服务..."
|
||||
|
||||
if [ -f "docker-compose.prod.yml" ]; then
|
||||
docker-compose -f docker-compose.prod.yml up -d
|
||||
else
|
||||
docker-compose up -d
|
||||
fi
|
||||
|
||||
log_info "服务启动完成"
|
||||
sleep 5
|
||||
show_status
|
||||
}
|
||||
|
||||
# 停止服务
|
||||
stop_services() {
|
||||
log_step "停止服务..."
|
||||
|
||||
if [ -f "docker-compose.prod.yml" ]; then
|
||||
docker-compose -f docker-compose.prod.yml down
|
||||
else
|
||||
docker-compose down
|
||||
fi
|
||||
|
||||
log_info "服务停止完成"
|
||||
}
|
||||
|
||||
# 重启服务
|
||||
restart_services() {
|
||||
local service_name=${1:-}
|
||||
|
||||
if [ -n "$service_name" ]; then
|
||||
log_step "重启服务: $service_name"
|
||||
docker-compose restart "$service_name"
|
||||
else
|
||||
log_step "重启所有服务..."
|
||||
stop_services
|
||||
sleep 3
|
||||
start_services
|
||||
fi
|
||||
}
|
||||
|
||||
# 查看服务状态
|
||||
show_status() {
|
||||
log_step "服务状态:"
|
||||
echo ""
|
||||
docker-compose ps
|
||||
echo ""
|
||||
|
||||
# 显示资源使用情况
|
||||
log_step "资源使用情况:"
|
||||
docker stats --no-stream --format "table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}\t{{.BlockIO}}"
|
||||
}
|
||||
|
||||
# 查看日志
|
||||
show_logs() {
|
||||
local follow_flag=""
|
||||
local service_name=""
|
||||
|
||||
# 解析参数
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
-f|--follow)
|
||||
follow_flag="-f"
|
||||
shift
|
||||
;;
|
||||
-s|--service)
|
||||
service_name="$2"
|
||||
shift 2
|
||||
;;
|
||||
*)
|
||||
service_name="$1"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -n "$service_name" ]; then
|
||||
log_info "查看服务日志: $service_name"
|
||||
docker-compose logs $follow_flag "$service_name"
|
||||
else
|
||||
log_info "查看所有服务日志"
|
||||
docker-compose logs $follow_flag
|
||||
fi
|
||||
}
|
||||
|
||||
# 备份数据
|
||||
backup_data() {
|
||||
local backup_dir="backups/$(date +%Y%m%d_%H%M%S)"
|
||||
|
||||
log_step "开始数据备份..."
|
||||
mkdir -p "$backup_dir"
|
||||
|
||||
# 备份MySQL数据
|
||||
log_info "备份MySQL数据..."
|
||||
docker-compose exec -T mysql mysqldump -u root -p123456 --all-databases > "$backup_dir/mysql_backup.sql"
|
||||
|
||||
# 备份Redis数据
|
||||
log_info "备份Redis数据..."
|
||||
docker-compose exec -T redis redis-cli BGSAVE
|
||||
docker cp $(docker-compose ps -q redis):/data/dump.rdb "$backup_dir/redis_backup.rdb"
|
||||
|
||||
# 备份配置文件
|
||||
log_info "备份配置文件..."
|
||||
cp -r deploy "$backup_dir/"
|
||||
cp docker-compose*.yml "$backup_dir/"
|
||||
cp .env "$backup_dir/" 2>/dev/null || true
|
||||
|
||||
# 压缩备份
|
||||
tar -czf "$backup_dir.tar.gz" -C backups "$(basename $backup_dir)"
|
||||
rm -rf "$backup_dir"
|
||||
|
||||
log_info "备份完成: $backup_dir.tar.gz"
|
||||
}
|
||||
|
||||
# 恢复数据
|
||||
restore_data() {
|
||||
local backup_file="$1"
|
||||
|
||||
if [ -z "$backup_file" ]; then
|
||||
log_error "请指定备份文件"
|
||||
echo "用法: $0 restore <backup_file.tar.gz>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$backup_file" ]; then
|
||||
log_error "备份文件不存在: $backup_file"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_step "开始数据恢复..."
|
||||
log_warn "此操作将覆盖现有数据,请确认后继续"
|
||||
read -p "是否继续? (y/N): " -n 1 -r
|
||||
echo
|
||||
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
log_info "恢复操作已取消"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# 解压备份文件
|
||||
local restore_dir="restore_$(date +%Y%m%d_%H%M%S)"
|
||||
mkdir -p "$restore_dir"
|
||||
tar -xzf "$backup_file" -C "$restore_dir"
|
||||
|
||||
# 恢复MySQL数据
|
||||
log_info "恢复MySQL数据..."
|
||||
docker-compose exec -T mysql mysql -u root -p123456 < "$restore_dir"/*/mysql_backup.sql
|
||||
|
||||
# 恢复Redis数据
|
||||
log_info "恢复Redis数据..."
|
||||
docker-compose stop redis
|
||||
docker cp "$restore_dir"/*/redis_backup.rdb $(docker-compose ps -q redis):/data/dump.rdb
|
||||
docker-compose start redis
|
||||
|
||||
# 清理临时文件
|
||||
rm -rf "$restore_dir"
|
||||
|
||||
log_info "数据恢复完成"
|
||||
}
|
||||
|
||||
# 更新服务
|
||||
update_services() {
|
||||
log_step "更新服务..."
|
||||
|
||||
# 拉取最新代码
|
||||
if [ -d ".git" ]; then
|
||||
log_info "拉取最新代码..."
|
||||
git pull
|
||||
fi
|
||||
|
||||
# 重新构建镜像
|
||||
log_info "重新构建镜像..."
|
||||
docker-compose build --no-cache
|
||||
|
||||
# 重启服务
|
||||
log_info "重启服务..."
|
||||
restart_services
|
||||
|
||||
log_info "服务更新完成"
|
||||
}
|
||||
|
||||
# 清理资源
|
||||
clean_resources() {
|
||||
log_step "清理Docker资源..."
|
||||
|
||||
log_warn "此操作将清理未使用的Docker资源"
|
||||
read -p "是否继续? (y/N): " -n 1 -r
|
||||
echo
|
||||
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
# 清理未使用的镜像
|
||||
docker image prune -f
|
||||
|
||||
# 清理未使用的容器
|
||||
docker container prune -f
|
||||
|
||||
# 清理未使用的网络
|
||||
docker network prune -f
|
||||
|
||||
# 清理未使用的卷(谨慎使用)
|
||||
# docker volume prune -f
|
||||
|
||||
log_info "资源清理完成"
|
||||
else
|
||||
log_info "清理操作已取消"
|
||||
fi
|
||||
}
|
||||
|
||||
# 监控服务
|
||||
monitor_services() {
|
||||
log_step "服务监控面板"
|
||||
echo ""
|
||||
|
||||
while true; do
|
||||
clear
|
||||
echo "=== 情绪博物馆服务监控 ==="
|
||||
echo "时间: $(date)"
|
||||
echo ""
|
||||
|
||||
# 显示服务状态
|
||||
echo "📊 服务状态:"
|
||||
docker-compose ps
|
||||
echo ""
|
||||
|
||||
# 显示资源使用
|
||||
echo "💻 资源使用:"
|
||||
docker stats --no-stream --format "table {{.Container}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}"
|
||||
echo ""
|
||||
|
||||
# 显示磁盘使用
|
||||
echo "💾 磁盘使用:"
|
||||
df -h | grep -E "(Filesystem|/dev/)"
|
||||
echo ""
|
||||
|
||||
echo "按 Ctrl+C 退出监控"
|
||||
sleep 5
|
||||
done
|
||||
}
|
||||
|
||||
# 健康检查
|
||||
health_check() {
|
||||
log_step "执行健康检查..."
|
||||
|
||||
local all_healthy=true
|
||||
|
||||
# 检查MySQL
|
||||
if docker-compose exec -T mysql mysqladmin ping -h localhost -u root -p123456 &> /dev/null; then
|
||||
log_info "✅ MySQL服务正常"
|
||||
else
|
||||
log_error "❌ MySQL服务异常"
|
||||
all_healthy=false
|
||||
fi
|
||||
|
||||
# 检查Redis
|
||||
if docker-compose exec -T redis redis-cli ping | grep -q PONG; then
|
||||
log_info "✅ Redis服务正常"
|
||||
else
|
||||
log_error "❌ Redis服务异常"
|
||||
all_healthy=false
|
||||
fi
|
||||
|
||||
# 检查Nacos
|
||||
if curl -s http://localhost:8848/nacos/v1/ns/operator/metrics &> /dev/null; then
|
||||
log_info "✅ Nacos服务正常"
|
||||
else
|
||||
log_error "❌ Nacos服务异常"
|
||||
all_healthy=false
|
||||
fi
|
||||
|
||||
# 检查网关
|
||||
if curl -s http://localhost:9000/actuator/health &> /dev/null; then
|
||||
log_info "✅ 网关服务正常"
|
||||
else
|
||||
log_error "❌ 网关服务异常"
|
||||
all_healthy=false
|
||||
fi
|
||||
|
||||
# 检查AI服务
|
||||
if curl -s http://localhost:9002/actuator/health &> /dev/null; then
|
||||
log_info "✅ AI服务正常"
|
||||
else
|
||||
log_error "❌ AI服务异常"
|
||||
all_healthy=false
|
||||
fi
|
||||
|
||||
# 检查前端
|
||||
if curl -s http://localhost:80/health &> /dev/null; then
|
||||
log_info "✅ 前端服务正常"
|
||||
else
|
||||
log_error "❌ 前端服务异常"
|
||||
all_healthy=false
|
||||
fi
|
||||
|
||||
if $all_healthy; then
|
||||
log_info "🎉 所有服务健康检查通过"
|
||||
else
|
||||
log_warn "⚠️ 部分服务存在问题,请检查日志"
|
||||
fi
|
||||
}
|
||||
|
||||
# 主函数
|
||||
main() {
|
||||
case "${1:-}" in
|
||||
"start")
|
||||
start_services
|
||||
;;
|
||||
"stop")
|
||||
stop_services
|
||||
;;
|
||||
"restart")
|
||||
shift
|
||||
restart_services "$@"
|
||||
;;
|
||||
"status")
|
||||
show_status
|
||||
;;
|
||||
"logs")
|
||||
shift
|
||||
show_logs "$@"
|
||||
;;
|
||||
"backup")
|
||||
backup_data
|
||||
;;
|
||||
"restore")
|
||||
restore_data "$2"
|
||||
;;
|
||||
"update")
|
||||
update_services
|
||||
;;
|
||||
"clean")
|
||||
clean_resources
|
||||
;;
|
||||
"monitor")
|
||||
monitor_services
|
||||
;;
|
||||
"health")
|
||||
health_check
|
||||
;;
|
||||
"-h"|"--help"|"help")
|
||||
show_help
|
||||
;;
|
||||
*)
|
||||
show_help
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
main "$@"
|
||||
@@ -0,0 +1,43 @@
|
||||
情绪博物馆部署包报告
|
||||
==================
|
||||
|
||||
构建信息:
|
||||
- 包名称: emotion-museum-1.0.0-20250713_123404.tar.gz
|
||||
- 构建时间: 20250713_123404
|
||||
- 构建环境: Darwin x86_64
|
||||
|
||||
包内容:
|
||||
- 前端构建产物 ✓
|
||||
- 后端JAR文件 ✓
|
||||
- 数据库脚本 ✓
|
||||
- 部署配置 ✓
|
||||
- Docker配置 ✓
|
||||
- 管理脚本 ✓
|
||||
- 说明文档 ✓
|
||||
|
||||
文件信息:
|
||||
- 压缩包大小: 680K
|
||||
- SHA256校验: f6fa31c425fbddaea30972db6425265cdad49761236d7a58fcb0fa001baea417
|
||||
|
||||
部署要求:
|
||||
- Docker 20.10+
|
||||
- Docker Compose 1.29+
|
||||
- 内存: 4GB+
|
||||
- 磁盘: 10GB+
|
||||
|
||||
快速部署:
|
||||
1. 解压: tar -xzf emotion-museum-1.0.0-20250713_123404.tar.gz
|
||||
2. 进入: cd emotion-museum-1.0.0-20250713_123404
|
||||
3. 配置: vim .env
|
||||
4. 部署: ./quick-deploy.sh
|
||||
|
||||
注意事项:
|
||||
- 请配置正确的Coze API Token
|
||||
- 生产环境请修改默认密码
|
||||
- 建议配置HTTPS证书
|
||||
- 确保防火墙开放必要端口
|
||||
|
||||
技术支持:
|
||||
- 详细文档: DEPLOY.md
|
||||
- 快速指南: QUICK_START.md
|
||||
- 管理命令: ./manage.sh --help
|
||||
Reference in New Issue
Block a user