mirror of
https://github.com/2930134478/AI-CS.git
synced 2026-06-15 00:44:30 +08:00
Add Docker deployment support and GitHub Actions
This commit is contained in:
@@ -0,0 +1,26 @@
|
|||||||
|
# Git
|
||||||
|
.git
|
||||||
|
.gitignore
|
||||||
|
|
||||||
|
# 环境变量文件
|
||||||
|
.env
|
||||||
|
.env.local
|
||||||
|
.env.production
|
||||||
|
|
||||||
|
# 文档
|
||||||
|
doc/
|
||||||
|
*.md
|
||||||
|
!README.md
|
||||||
|
|
||||||
|
# IDE
|
||||||
|
.vscode
|
||||||
|
.idea
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
|
||||||
|
# 日志
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# 系统文件
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
# ============================================
|
||||||
|
# AI-CS 系统 Docker 部署配置模板
|
||||||
|
# ============================================
|
||||||
|
# 使用方法:
|
||||||
|
# 1. 复制此文件为 .env:cp .env.example .env
|
||||||
|
# 2. 编辑 .env 文件,修改以下配置
|
||||||
|
# 3. .env 文件不要提交到 Git!
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# MySQL 数据库配置
|
||||||
|
# ============================================
|
||||||
|
MYSQL_ROOT_PASSWORD=rootpassword
|
||||||
|
MYSQL_DATABASE=ai_cs
|
||||||
|
MYSQL_USER=ai_cs_user
|
||||||
|
MYSQL_PASSWORD=ai_cs_password
|
||||||
|
MYSQL_PORT=3306
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# 后端服务配置
|
||||||
|
# ============================================
|
||||||
|
BACKEND_PORT=8080
|
||||||
|
ADMIN_USERNAME=admin
|
||||||
|
ADMIN_PASSWORD=admin123
|
||||||
|
GIN_MODE=release
|
||||||
|
|
||||||
|
# 加密密钥(用于加密 AI API Keys)
|
||||||
|
# 生成方式:
|
||||||
|
# - Linux/Mac: openssl rand -hex 32
|
||||||
|
# - Windows PowerShell: -join ((48..57) + (97..102) | Get-Random -Count 64 | ForEach-Object {[char]$_})
|
||||||
|
# - 在线工具: https://www.random.org/strings/?num=1&len=64&digits=on&upperalpha=off&loweralpha=on&unique=off&format=html&rnd=new
|
||||||
|
ENCRYPTION_KEY=changeme_please_use_random_hex_32_bytes_here
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# 前端服务配置
|
||||||
|
# ============================================
|
||||||
|
FRONTEND_PORT=3000
|
||||||
|
# 前端访问后端的地址(Docker 内部使用容器名,外部访问使用 localhost)
|
||||||
|
NEXT_PUBLIC_API_BASE_URL=http://localhost:8080
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# 生产版镜像配置(仅用于 docker-compose.prod.yml)
|
||||||
|
# ============================================
|
||||||
|
# 如果使用预构建镜像,可以指定镜像名称(可选)
|
||||||
|
# BACKEND_IMAGE=2930134478/ai-cs-backend:latest
|
||||||
|
# FRONTEND_IMAGE=2930134478/ai-cs-frontend:latest
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
name: Build and Push Docker Image
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ main ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- name: Build and push
|
||||||
|
uses: docker/build-push-action@v4
|
||||||
|
with:
|
||||||
|
push: true
|
||||||
|
tags: 537yaha/ai-cs:latest
|
||||||
@@ -24,20 +24,179 @@
|
|||||||
|
|
||||||
## 🚀 快速开始
|
## 🚀 快速开始
|
||||||
|
|
||||||
### 环境要求
|
### 方式一:预构建镜像一键部署(推荐,最简单)⭐
|
||||||
|
|
||||||
- Go 1.21 或更高版本
|
> **最简单快捷的方式**,直接使用预构建的 Docker 镜像,无需构建,一行命令启动。
|
||||||
- Node.js 18+ 和 npm/yarn
|
|
||||||
- MySQL 8.0 或更高版本
|
|
||||||
|
|
||||||
### 1. 克隆项目
|
#### 前置要求
|
||||||
|
|
||||||
|
- Docker Desktop(Windows/Mac)或 Docker + Docker Compose(Linux)
|
||||||
|
|
||||||
|
#### 部署步骤
|
||||||
|
|
||||||
|
1. **克隆项目并进入目录**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone https://github.com/2930134478/AI-CS.git
|
git clone https://github.com/2930134478/AI-CS.git
|
||||||
cd AI-CS
|
cd AI-CS
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2. 配置后端
|
2. **配置环境变量**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 复制环境变量模板
|
||||||
|
cp .env.example .env
|
||||||
|
|
||||||
|
# 编辑 .env 文件,至少修改以下配置:
|
||||||
|
# - MYSQL_ROOT_PASSWORD: MySQL root 密码
|
||||||
|
# - ADMIN_PASSWORD: 管理员密码(首次登录使用)
|
||||||
|
# - ENCRYPTION_KEY: 加密密钥(生成 64 位十六进制字符串)
|
||||||
|
```
|
||||||
|
|
||||||
|
生成加密密钥:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Linux/Mac
|
||||||
|
openssl rand -hex 32
|
||||||
|
|
||||||
|
# Windows PowerShell
|
||||||
|
-join ((48..57) + (97..102) | Get-Random -Count 64 | ForEach-Object {[char]$_})
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **一键启动**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 使用预构建镜像启动(自动从 Docker Hub 拉取镜像)
|
||||||
|
docker-compose -f docker-compose.prod.yml up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
就这么简单!🎉
|
||||||
|
|
||||||
|
4. **访问应用**
|
||||||
|
|
||||||
|
- **前端首页**: http://localhost:3000
|
||||||
|
- **访客聊天**: http://localhost:3000/chat
|
||||||
|
- **客服登录**: http://localhost:3000/agent/login
|
||||||
|
- 用户名:`admin`(或 `.env` 中配置的 `ADMIN_USERNAME`)
|
||||||
|
- 密码:`.env` 中配置的 `ADMIN_PASSWORD`
|
||||||
|
|
||||||
|
#### 常用命令
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 查看日志
|
||||||
|
docker-compose -f docker-compose.prod.yml logs -f
|
||||||
|
|
||||||
|
# 查看服务状态
|
||||||
|
docker-compose -f docker-compose.prod.yml ps
|
||||||
|
|
||||||
|
# 停止服务
|
||||||
|
docker-compose -f docker-compose.prod.yml stop
|
||||||
|
|
||||||
|
# 停止并删除容器(保留数据)
|
||||||
|
docker-compose -f docker-compose.prod.yml down
|
||||||
|
|
||||||
|
# 完全重置(删除所有数据)
|
||||||
|
docker-compose -f docker-compose.prod.yml down -v
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 方式二:Docker 本地构建部署
|
||||||
|
|
||||||
|
> 适合需要自定义构建或网络无法访问 Docker Hub 的情况。
|
||||||
|
|
||||||
|
#### 前置要求
|
||||||
|
|
||||||
|
- Docker Desktop(Windows/Mac)或 Docker + Docker Compose(Linux)
|
||||||
|
- Git
|
||||||
|
|
||||||
|
#### 部署步骤
|
||||||
|
|
||||||
|
1. **克隆项目**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/2930134478/AI-CS.git
|
||||||
|
cd AI-CS
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **配置环境变量**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 复制环境变量模板
|
||||||
|
cp .env.example .env
|
||||||
|
|
||||||
|
# 编辑 .env 文件,至少修改以下配置:
|
||||||
|
# - MYSQL_ROOT_PASSWORD: MySQL root 密码
|
||||||
|
# - ADMIN_PASSWORD: 管理员密码(首次登录使用)
|
||||||
|
# - ENCRYPTION_KEY: 加密密钥(生成 64 位十六进制字符串)
|
||||||
|
```
|
||||||
|
|
||||||
|
生成加密密钥:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Linux/Mac
|
||||||
|
openssl rand -hex 32
|
||||||
|
|
||||||
|
# Windows PowerShell
|
||||||
|
-join ((48..57) + (97..102) | Get-Random -Count 64 | ForEach-Object {[char]$_})
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **构建并启动服务**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 构建并启动所有服务(首次构建需要一些时间)
|
||||||
|
docker-compose up -d --build
|
||||||
|
|
||||||
|
# 查看日志
|
||||||
|
docker-compose logs -f
|
||||||
|
|
||||||
|
# 查看服务状态
|
||||||
|
docker-compose ps
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **访问应用**
|
||||||
|
|
||||||
|
- **前端首页**: http://localhost:3000
|
||||||
|
- **访客聊天**: http://localhost:3000/chat
|
||||||
|
- **客服登录**: http://localhost:3000/agent/login
|
||||||
|
- 用户名:`admin`(或 `.env` 中配置的 `ADMIN_USERNAME`)
|
||||||
|
- 密码:`.env` 中配置的 `ADMIN_PASSWORD`
|
||||||
|
|
||||||
|
#### 常用命令
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 停止服务
|
||||||
|
docker-compose stop
|
||||||
|
|
||||||
|
# 停止并删除容器(保留数据)
|
||||||
|
docker-compose down
|
||||||
|
|
||||||
|
# 完全重置(删除所有数据)
|
||||||
|
docker-compose down -v
|
||||||
|
|
||||||
|
# 查看日志
|
||||||
|
docker-compose logs -f backend
|
||||||
|
docker-compose logs -f frontend
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 方式三:传统部署(手动安装)
|
||||||
|
|
||||||
|
#### 环境要求
|
||||||
|
|
||||||
|
- Go 1.24 或更高版本
|
||||||
|
- Node.js 18+ 和 npm/yarn
|
||||||
|
- MySQL 8.0 或更高版本
|
||||||
|
|
||||||
|
#### 1. 克隆项目
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/2930134478/AI-CS.git
|
||||||
|
cd AI-CS
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2. 配置后端
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd backend
|
cd backend
|
||||||
@@ -73,7 +232,7 @@ go run main.go
|
|||||||
|
|
||||||
> ⚠️ **重要**:`ADMIN_PASSWORD` 是必填项,如果不设置,系统不会创建默认管理员账号。
|
> ⚠️ **重要**:`ADMIN_PASSWORD` 是必填项,如果不设置,系统不会创建默认管理员账号。
|
||||||
|
|
||||||
### 3. 配置前端
|
#### 3. 配置前端
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd frontend
|
cd frontend
|
||||||
@@ -85,7 +244,7 @@ npm install
|
|||||||
npm run dev
|
npm run dev
|
||||||
```
|
```
|
||||||
|
|
||||||
### 4. 访问应用
|
#### 4. 访问应用
|
||||||
|
|
||||||
- **官网首页**: http://localhost:3000
|
- **官网首页**: http://localhost:3000
|
||||||
- **访客聊天**:
|
- **访客聊天**:
|
||||||
@@ -93,7 +252,7 @@ npm run dev
|
|||||||
- 或点击首页右下角的客服插件按钮
|
- 或点击首页右下角的客服插件按钮
|
||||||
- **客服登录**: http://localhost:3000/agent/login
|
- **客服登录**: http://localhost:3000/agent/login
|
||||||
|
|
||||||
### 5. 默认管理员账号
|
#### 5. 默认管理员账号
|
||||||
|
|
||||||
⚠️ **重要说明**:
|
⚠️ **重要说明**:
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
# Git
|
||||||
|
.git
|
||||||
|
.gitignore
|
||||||
|
|
||||||
|
# 编译产物
|
||||||
|
backend.exe
|
||||||
|
backend
|
||||||
|
*.exe
|
||||||
|
*.dll
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# 环境变量
|
||||||
|
.env
|
||||||
|
.env.local
|
||||||
|
|
||||||
|
# 上传文件(保留目录结构但不包含文件)
|
||||||
|
uploads/*
|
||||||
|
!uploads/.gitkeep
|
||||||
|
|
||||||
|
# 日志
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# IDE
|
||||||
|
.vscode
|
||||||
|
.idea
|
||||||
|
*.swp
|
||||||
|
|
||||||
|
# 系统文件
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# 其他
|
||||||
|
node_modules
|
||||||
|
package.json
|
||||||
|
package-lock.json
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
# ============================================
|
||||||
|
# 多阶段构建:构建阶段
|
||||||
|
# ============================================
|
||||||
|
FROM golang:1.24-alpine AS builder
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# 安装必要的构建工具
|
||||||
|
RUN apk add --no-cache git ca-certificates tzdata
|
||||||
|
|
||||||
|
# 复制 go mod 文件
|
||||||
|
COPY go.mod go.sum ./
|
||||||
|
|
||||||
|
# 下载依赖
|
||||||
|
RUN go mod download
|
||||||
|
|
||||||
|
# 复制源代码
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
# 构建应用
|
||||||
|
# CGO_ENABLED=0: 禁用 CGO,生成纯 Go 二进制文件
|
||||||
|
# GOOS=linux: 目标操作系统
|
||||||
|
# GOARCH=amd64: 目标架构
|
||||||
|
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -installsuffix cgo -ldflags '-extldflags "-static"' -o backend main.go
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# 运行阶段
|
||||||
|
# ============================================
|
||||||
|
FROM alpine:latest
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# 安装必要的运行时依赖
|
||||||
|
RUN apk --no-cache add ca-certificates tzdata
|
||||||
|
|
||||||
|
# 从构建阶段复制二进制文件
|
||||||
|
COPY --from=builder /app/backend .
|
||||||
|
|
||||||
|
# 从构建阶段复制时区数据(可选)
|
||||||
|
COPY --from=builder /usr/share/zoneinfo /usr/share/zoneinfo
|
||||||
|
|
||||||
|
# 设置时区(可选,默认 UTC)
|
||||||
|
ENV TZ=Asia/Shanghai
|
||||||
|
|
||||||
|
# 创建必要的目录
|
||||||
|
RUN mkdir -p uploads/avatars uploads/messages
|
||||||
|
|
||||||
|
# 暴露端口
|
||||||
|
EXPOSE 8080
|
||||||
|
|
||||||
|
# 启动应用
|
||||||
|
CMD ["./backend"]
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
|
||||||
|
|
||||||
|
services:
|
||||||
|
# MySQL 数据库
|
||||||
|
mysql:
|
||||||
|
image: mysql:8.0
|
||||||
|
container_name: ai-cs-mysql
|
||||||
|
environment:
|
||||||
|
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-rootpassword}
|
||||||
|
MYSQL_DATABASE: ${MYSQL_DATABASE:-ai_cs}
|
||||||
|
MYSQL_USER: ${MYSQL_USER:-ai_cs_user}
|
||||||
|
MYSQL_PASSWORD: ${MYSQL_PASSWORD:-ai_cs_password}
|
||||||
|
ports:
|
||||||
|
- "${MYSQL_PORT:-3306}:3306"
|
||||||
|
volumes:
|
||||||
|
- mysql_data:/var/lib/mysql
|
||||||
|
command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p${MYSQL_ROOT_PASSWORD:-rootpassword}"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
start_period: 30s
|
||||||
|
networks:
|
||||||
|
- ai-cs-network
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
# 后端服务(使用预构建镜像)
|
||||||
|
backend:
|
||||||
|
image: ${BACKEND_IMAGE:-537yaha/ai-cs-backend:latest}
|
||||||
|
container_name: ai-cs-backend
|
||||||
|
environment:
|
||||||
|
DB_HOST: mysql
|
||||||
|
DB_PORT: 3306
|
||||||
|
DB_USER: ${MYSQL_USER:-ai_cs_user}
|
||||||
|
DB_PASSWORD: ${MYSQL_PASSWORD:-ai_cs_password}
|
||||||
|
DB_NAME: ${MYSQL_DATABASE:-ai_cs}
|
||||||
|
ADMIN_USERNAME: ${ADMIN_USERNAME:-admin}
|
||||||
|
ADMIN_PASSWORD: ${ADMIN_PASSWORD:-admin123}
|
||||||
|
SERVER_HOST: 0.0.0.0
|
||||||
|
SERVER_PORT: 8080
|
||||||
|
GIN_MODE: ${GIN_MODE:-release}
|
||||||
|
ENCRYPTION_KEY: ${ENCRYPTION_KEY:-default-key}
|
||||||
|
ports:
|
||||||
|
- "${BACKEND_PORT:-8080}:8080"
|
||||||
|
volumes:
|
||||||
|
- ./backend/uploads:/app/uploads
|
||||||
|
depends_on:
|
||||||
|
mysql:
|
||||||
|
condition: service_healthy
|
||||||
|
networks:
|
||||||
|
- ai-cs-network
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
# 前端服务(使用预构建镜像)
|
||||||
|
frontend:
|
||||||
|
image: ${FRONTEND_IMAGE:-537yaha/ai-cs-frontend:latest}
|
||||||
|
container_name: ai-cs-frontend
|
||||||
|
environment:
|
||||||
|
NEXT_PUBLIC_API_BASE_URL: ${NEXT_PUBLIC_API_BASE_URL:-http://localhost:8080}
|
||||||
|
ports:
|
||||||
|
- "${FRONTEND_PORT:-3000}:3000"
|
||||||
|
depends_on:
|
||||||
|
- backend
|
||||||
|
networks:
|
||||||
|
- ai-cs-network
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
mysql_data:
|
||||||
|
driver: local
|
||||||
|
|
||||||
|
networks:
|
||||||
|
ai-cs-network:
|
||||||
|
driver: bridge
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
|
||||||
|
|
||||||
|
services:
|
||||||
|
# MySQL 数据库
|
||||||
|
mysql:
|
||||||
|
image: mysql:8.0
|
||||||
|
container_name: ai-cs-mysql
|
||||||
|
environment:
|
||||||
|
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-rootpassword}
|
||||||
|
MYSQL_DATABASE: ${MYSQL_DATABASE:-ai_cs}
|
||||||
|
MYSQL_USER: ${MYSQL_USER:-ai_cs_user}
|
||||||
|
MYSQL_PASSWORD: ${MYSQL_PASSWORD:-ai_cs_password}
|
||||||
|
ports:
|
||||||
|
- "${MYSQL_PORT:-3306}:3306"
|
||||||
|
volumes:
|
||||||
|
- mysql_data:/var/lib/mysql
|
||||||
|
command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p${MYSQL_ROOT_PASSWORD:-rootpassword}"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
start_period: 30s
|
||||||
|
networks:
|
||||||
|
- ai-cs-network
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
# 后端服务(本地构建)
|
||||||
|
backend:
|
||||||
|
build:
|
||||||
|
context: ./backend
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: ai-cs-backend
|
||||||
|
environment:
|
||||||
|
DB_HOST: mysql
|
||||||
|
DB_PORT: 3306
|
||||||
|
DB_USER: ${MYSQL_USER:-ai_cs_user}
|
||||||
|
DB_PASSWORD: ${MYSQL_PASSWORD:-ai_cs_password}
|
||||||
|
DB_NAME: ${MYSQL_DATABASE:-ai_cs}
|
||||||
|
ADMIN_USERNAME: ${ADMIN_USERNAME:-admin}
|
||||||
|
ADMIN_PASSWORD: ${ADMIN_PASSWORD:-admin123}
|
||||||
|
SERVER_HOST: 0.0.0.0
|
||||||
|
SERVER_PORT: 8080
|
||||||
|
GIN_MODE: ${GIN_MODE:-release}
|
||||||
|
ENCRYPTION_KEY: ${ENCRYPTION_KEY:-default-key}
|
||||||
|
ports:
|
||||||
|
- "${BACKEND_PORT:-8080}:8080"
|
||||||
|
volumes:
|
||||||
|
- ./backend/uploads:/app/uploads
|
||||||
|
depends_on:
|
||||||
|
mysql:
|
||||||
|
condition: service_healthy
|
||||||
|
networks:
|
||||||
|
- ai-cs-network
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
# 前端服务(本地构建)
|
||||||
|
frontend:
|
||||||
|
build:
|
||||||
|
context: ./frontend
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
args:
|
||||||
|
NEXT_PUBLIC_API_BASE_URL: ${NEXT_PUBLIC_API_BASE_URL:-http://localhost:8080}
|
||||||
|
container_name: ai-cs-frontend
|
||||||
|
ports:
|
||||||
|
- "${FRONTEND_PORT:-3000}:3000"
|
||||||
|
depends_on:
|
||||||
|
- backend
|
||||||
|
networks:
|
||||||
|
- ai-cs-network
|
||||||
|
restart: unless-stopped
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
mysql_data:
|
||||||
|
driver: local
|
||||||
|
|
||||||
|
networks:
|
||||||
|
ai-cs-network:
|
||||||
|
driver: bridge
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
# Git
|
||||||
|
.git
|
||||||
|
.gitignore
|
||||||
|
|
||||||
|
# 环境变量
|
||||||
|
.env
|
||||||
|
.env.local
|
||||||
|
.env.production
|
||||||
|
.env.development
|
||||||
|
|
||||||
|
# 构建产物
|
||||||
|
.next
|
||||||
|
dist
|
||||||
|
out
|
||||||
|
build
|
||||||
|
|
||||||
|
# 依赖
|
||||||
|
node_modules
|
||||||
|
|
||||||
|
# 日志
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
|
||||||
|
# IDE
|
||||||
|
.vscode
|
||||||
|
.idea
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
|
||||||
|
# 测试
|
||||||
|
coverage
|
||||||
|
.nyc_output
|
||||||
|
|
||||||
|
# 系统文件
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# 其他
|
||||||
|
*.tsbuildinfo
|
||||||
|
.eslintcache
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
# ============================================
|
||||||
|
# 多阶段构建:构建阶段
|
||||||
|
# ============================================
|
||||||
|
FROM node:18-alpine AS builder
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# 复制 package 文件
|
||||||
|
COPY package*.json ./
|
||||||
|
|
||||||
|
# 安装依赖(使用 npm ci 确保依赖版本一致)
|
||||||
|
RUN npm ci
|
||||||
|
|
||||||
|
# 复制源代码
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
# 构建参数(Next.js 环境变量必须在构建时传入)
|
||||||
|
ARG NEXT_PUBLIC_API_BASE_URL
|
||||||
|
ENV NEXT_PUBLIC_API_BASE_URL=$NEXT_PUBLIC_API_BASE_URL
|
||||||
|
|
||||||
|
# 构建 Next.js 应用
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# 运行阶段
|
||||||
|
# ============================================
|
||||||
|
FROM node:18-alpine
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# 设置生产环境
|
||||||
|
ENV NODE_ENV=production
|
||||||
|
|
||||||
|
# 复制 package 文件(用于安装生产依赖)
|
||||||
|
COPY package*.json ./
|
||||||
|
|
||||||
|
# 只安装生产依赖
|
||||||
|
RUN npm ci --only=production && npm cache clean --force
|
||||||
|
|
||||||
|
# 从构建阶段复制必要的文件
|
||||||
|
COPY --from=builder /app/next.config.ts ./
|
||||||
|
COPY --from=builder /app/tsconfig.json ./
|
||||||
|
COPY --from=builder /app/public ./public
|
||||||
|
COPY --from=builder /app/.next ./.next
|
||||||
|
|
||||||
|
# 暴露端口
|
||||||
|
EXPOSE 3000
|
||||||
|
|
||||||
|
# 启动 Next.js 生产服务器
|
||||||
|
CMD ["npm", "start"]
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
# 前端配置说明
|
|
||||||
|
|
||||||
## 真实设备测试配置
|
|
||||||
|
|
||||||
### 步骤 1:创建 `.env.local` 文件
|
|
||||||
|
|
||||||
在 `frontend` 目录下创建 `.env.local` 文件(如果不存在)。
|
|
||||||
|
|
||||||
### 步骤 2:配置 IP 地址
|
|
||||||
|
|
||||||
在 `.env.local` 文件中添加以下内容:
|
|
||||||
|
|
||||||
```env
|
|
||||||
# 将 192.168.124.9 替换为你的电脑 IP 地址
|
|
||||||
# 获取 IP 地址:在 PowerShell 中运行 ipconfig
|
|
||||||
NEXT_PUBLIC_API_BASE_URL=http://192.168.124.9:8080
|
|
||||||
```
|
|
||||||
|
|
||||||
**你的 IP 地址**:根据 `ipconfig` 结果,你的 IP 地址是 **192.168.124.9**
|
|
||||||
|
|
||||||
### 步骤 3:重启前端服务
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 停止当前服务(Ctrl+C)
|
|
||||||
# 重新启动
|
|
||||||
npm run dev
|
|
||||||
```
|
|
||||||
|
|
||||||
### 步骤 4:在手机/平板上访问
|
|
||||||
|
|
||||||
1. 确保手机/平板连接**同一 WiFi**
|
|
||||||
2. 在手机浏览器输入:`http://192.168.124.9:3000`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 本地开发配置(默认)
|
|
||||||
|
|
||||||
如果只想在本地开发,不需要配置 `.env.local` 文件,使用默认配置即可:
|
|
||||||
|
|
||||||
- 前端:`http://localhost:3000`
|
|
||||||
- 后端:`http://127.0.0.1:8080`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 注意事项
|
|
||||||
|
|
||||||
1. ✅ **防火墙**:确保 Windows 防火墙允许端口 3000 和 8080
|
|
||||||
2. ✅ **同一网络**:手机和电脑必须在同一 WiFi 网络
|
|
||||||
3. ✅ **后端配置**:后端已配置为监听 `0.0.0.0:8080`,允许外部访问
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 快速配置
|
|
||||||
|
|
||||||
**Windows PowerShell**:
|
|
||||||
|
|
||||||
```powershell
|
|
||||||
# 在 frontend 目录下运行
|
|
||||||
@"
|
|
||||||
NEXT_PUBLIC_API_BASE_URL=http://192.168.124.9:8080
|
|
||||||
"@ | Out-File -FilePath ".env.local" -Encoding utf8
|
|
||||||
```
|
|
||||||
|
|
||||||
(记得将 `192.168.124.9` 替换为你的实际 IP 地址)
|
|
||||||
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app).
|
|
||||||
|
|
||||||
## Getting Started
|
|
||||||
|
|
||||||
First, run the development server:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
npm run dev
|
|
||||||
# or
|
|
||||||
yarn dev
|
|
||||||
# or
|
|
||||||
pnpm dev
|
|
||||||
# or
|
|
||||||
bun dev
|
|
||||||
```
|
|
||||||
|
|
||||||
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
|
|
||||||
|
|
||||||
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
|
|
||||||
|
|
||||||
This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.
|
|
||||||
|
|
||||||
## Learn More
|
|
||||||
|
|
||||||
To learn more about Next.js, take a look at the following resources:
|
|
||||||
|
|
||||||
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
|
|
||||||
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
|
|
||||||
|
|
||||||
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!
|
|
||||||
|
|
||||||
## Deploy on Vercel
|
|
||||||
|
|
||||||
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
|
|
||||||
|
|
||||||
Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
|
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import type { Metadata } from "next";
|
import type { Metadata } from "next";
|
||||||
import { Geist, Geist_Mono } from "next/font/google";
|
import { Geist, Geist_Mono } from "next/font/google";
|
||||||
import "./globals.css";
|
import "./globals.css";
|
||||||
|
import MatomoTracker from "@/components/MatomoTracker";
|
||||||
|
|
||||||
const geistSans = Geist({
|
const geistSans = Geist({
|
||||||
variable: "--font-geist-sans",
|
variable: "--font-geist-sans",
|
||||||
@@ -17,6 +18,9 @@ export const metadata: Metadata = {
|
|||||||
description: "融合 AI 技术与人工客服,为企业提供高效、智能的客户服务解决方案",
|
description: "融合 AI 技术与人工客服,为企业提供高效、智能的客户服务解决方案",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Matomo 容器 URL(格式:container_*.js)
|
||||||
|
const MATOMO_CONTAINER_URL = process.env.NEXT_PUBLIC_MATOMO_CONTAINER_URL || '';
|
||||||
|
|
||||||
export default function RootLayout({
|
export default function RootLayout({
|
||||||
children,
|
children,
|
||||||
}: Readonly<{
|
}: Readonly<{
|
||||||
@@ -28,6 +32,7 @@ export default function RootLayout({
|
|||||||
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
|
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
{MATOMO_CONTAINER_URL && <MatomoTracker containerUrl={MATOMO_CONTAINER_URL} />}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { useEffect } from 'react';
|
||||||
|
|
||||||
|
interface MatomoTrackerProps {
|
||||||
|
containerUrl?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function MatomoTracker({ containerUrl }: MatomoTrackerProps) {
|
||||||
|
useEffect(() => {
|
||||||
|
if (!containerUrl) {
|
||||||
|
console.warn('Matomo 容器 URL 未配置');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化 Matomo Tag Manager
|
||||||
|
const _mtm = (window._mtm = window._mtm || []);
|
||||||
|
_mtm.push({ 'mtm.startTime': new Date().getTime(), event: 'mtm.Start' });
|
||||||
|
|
||||||
|
const d = document;
|
||||||
|
const g = d.createElement('script');
|
||||||
|
const s = d.getElementsByTagName('script')[0];
|
||||||
|
|
||||||
|
g.async = true;
|
||||||
|
g.src = containerUrl;
|
||||||
|
if (s.parentNode) {
|
||||||
|
s.parentNode.insertBefore(g, s);
|
||||||
|
}
|
||||||
|
}, [containerUrl]);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user