chore: 添加部署配置及文档

- 新增 deploy/ 目录包含 Docker 部署配置、数据库脚本、部署脚本
- 更新 .gitignore 忽略 deploy 构建产物
- 添加 AGENTS.md AI Agent 指南
- 添加项目构建脚本 build.sh
This commit is contained in:
tangweijie 2026-01-22 21:10:49 +08:00
parent c3d172a5d9
commit bc40155ef0
23 changed files with 8030 additions and 2 deletions

View File

@ -0,0 +1,9 @@
---
name: usecluade
description: This is a new rule
---
# Overview
Insert overview text here. The agent will only see this should they choose to apply the rule.
请使用CLAUDE.md中的规则来回答问题。

7
.gitignore vendored
View File

@ -14,6 +14,13 @@ Thumbs.db
.history/
codegen/
# ========== Deploy ==========
deploy/xlcp-images/
deploy/data/
deploy/logs/
deploy/*/target/
deploy/*/dist/
# ========== Frontend (separate repo) ==========
frontend/
node_modules/

154
AGENTS.md Normal file
View File

@ -0,0 +1,154 @@
# AGENTS.md
This file provides guidance for AI agents working on the XL Prison Management System codebase.
## Project Overview
XL监狱综合管理平台 - A prison management platform built on the Yudao (芋道) framework.
**Tech Stack**: Java 17, Spring Boot 3.5.9, MyBatis-Plus, Vue 3.5.12, TypeScript 5.3.3, Element Plus, MySQL 8.0+
## Essential Commands
### Backend (Maven)
```bash
# Build all modules
cd backend && mvn clean install -DskipTests
# Build prison module only
cd backend/yudao-module-prison && mvn clean package
# Run dev server (port 48080)
cd backend/yudao-server && mvn spring-boot:run
# Run all tests
cd backend/yudao-module-prison && mvn test
# Run single test class
mvn test -Dtest=PrisonAreaControllerTest
# Force update dependencies
mvn clean install -U
```
### Frontend (pnpm)
```bash
cd frontend
# Install dependencies
pnpm install
# Dev server (local mode)
pnpm dev
# TypeScript checking
pnpm ts:check
# Build for different environments
pnpm build:local # Uses .env.local
pnpm build:dev # Uses .env.dev
pnpm build:prod # Uses .env.prod
# Linting
pnpm lint:eslint # ESLint check & fix (.js,.ts,.vue)
pnpm lint:format # Prettier format
pnpm lint:style # Stylelint fix
```
### Quick Start with Make
```bash
make frontend # Start frontend dev server
make backend # Start backend dev server
make run # Start both
```
## Code Style Guidelines
### Java (Backend)
**Imports**: Grouped by: Spring → Yudao → Third-party → Java stdlib. No wildcard imports.
**Naming Conventions**:
- Classes: PascalCase (e.g., `PrisonAreaController`, `ScoreDO`)
- Variables/Methods: camelCase (e.g., `getPage()`, `updateTime`)
- Constants: UPPER_SNAKE_CASE (e.g., `DEFAULT_PAGE_SIZE`)
- Package: `cn.iocoder.yudao.module.prison.{module}`
**VO Naming**: `SaveReqVO`, `PageReqVO`, `RespVO` suffixes required.
**Annotations**: Place on separate lines. Order: `@RestController``@RequestMapping``@Tag``@PreAuthorize`.
**Error Handling**: Use `CommonResult<T>` return type. Throw `ServiceException` for business errors with error codes from `ErrorCodeConstants`.
**Comments**: No comments unless explaining complex business logic. Javadoc only on public APIs.
### TypeScript/Vue (Frontend)
**Imports**: Sorted alphabetically. No unused imports. Use absolute imports (`@/`).
**Naming**:
- Interfaces: PascalCase (e.g., `Area`, `QuestionnaireRecord`)
- Variables/Props: camelCase
- Components: PascalCase file names, kebab-case usage
**Types**: Avoid `any`. Use explicit types or `unknown` for union types.
**Vue Composition API**: Use `<script setup lang="ts">`. Use composables from `@/hooks`.
**Formatting**: Use Prettier (80 char line width). Vue single-file components: `<script>``<template>``<style>`.
**Error Handling**: Wrap async API calls in try/catch with user feedback.
## Architecture Patterns
### Backend Structure
```
controller/admin/{module}/ # REST API + VOs
service/{module}/ # Business logic
dal/dataobject/{module}/ # MyBatis-Plus entities
dal/mysql/{module}/ # Mappers
convert/{module}/ # MapStruct converters
enums/ # Enum definitions
```
### Frontend Structure
```
views/prison/{module}/ # Page components
api/prison/{module}/ # API definitions + types
types/ # Shared TypeScript types
hooks/ # Composables
```
### Data Flow
Vue Component → API Layer → Controller → Service → Mapper → MySQL
## Database Conventions
- Table prefix: `prison_{module}` (e.g., `prison_area`, `prison_score`)
- Common fields: `id`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`
- Soft delete via `deleted` bit(1) field
- Use existing SQL migration scripts in `backend/sql/`
## API Conventions
- Base path: `/admin-api/prison/{module}`
- Permission pattern: `prison:{module}:{action}` (e.g., `prison:area:create`)
- Mock auth: `Authorization: Bearer emsoft{userId}` + `tenant-id: 1` header
## Cursor Rules
- Follow CLAUDE.md for technical decisions
- Reference `.cursor/rules/usecluade.mdc` for Chinese language context
## Testing
- Backend tests: `src/test/java/...` with `-Test` suffix
- Run specific test: `mvn test -Dtest=ClassName`
- Frontend: Manual testing via `pnpm dev` + browser dev tools
## Important Notes
- Never commit secrets or credentials
- Use mock mode for API testing (enabled in `application-local.yaml`)
- Default backend port: 48080
- Use `pnpm` for frontend, not `npm` or `yarn`

@ -1 +1 @@
Subproject commit 1eb543d803888ddf4d98260776032ad9829b5b3c
Subproject commit f252c69dd2c2d20c4112ee62ee86a0fb1a09fc62

162
build.sh Normal file
View File

@ -0,0 +1,162 @@
#!/bin/bash
# ============================================
# XL监狱综合管理平台 - 前后端编译脚本
# ============================================
# 功能:
# 1. 编译后端 Java 项目
# 2. 编译前端 Vue3 项目
# 3. 生成部署包
#
# 使用方法:
# 1. 修改下面的配置(可选)
# 2. 执行: bash build.sh
#
# 依赖:
# - Maven 3.8+
# - Node.js 16+
# - pnpm
# ============================================
# 配置
PROJECT_DIR="/Volumes/Dpan/github/xlcp"
BACKEND_DIR="${PROJECT_DIR}/backend"
FRONTEND_DIR="${PROJECT_DIR}/frontend"
BACKEND_OUTPUT_DIR="${PROJECT_DIR}/deploy/backend"
FRONTEND_OUTPUT_DIR="${PROJECT_DIR}/deploy/frontend"
# Maven 配置
MAVEN_PROFILE="prod"
JAVA_VERSION="17"
# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
echo -e "${GREEN}========================================${NC}"
echo -e "${GREEN}XL监狱综合管理平台 - 前后端编译脚本${NC}"
echo -e "${GREEN}========================================${NC}"
echo ""
# 检查依赖
echo -e "${BLUE}📋 检查编译环境...${NC}"
# 检查 Maven
if ! command -v mvn &> /dev/null; then
echo -e "${RED}❌ 错误: 未找到 Maven请先安装 Maven${NC}"
exit 1
fi
echo -e "${GREEN}✅ Maven 版本: $(mvn -version | head -1)${NC}"
# 检查 Node.js
if ! command -v node &> /dev/null; then
echo -e "${RED}❌ 错误: 未找到 Node.js请先安装 Node.js${NC}"
exit 1
fi
echo -e "${GREEN}✅ Node.js 版本: $(node -v)${NC}"
# 检查 pnpm
if ! command -v pnpm &> /dev/null; then
echo -e "${YELLOW}⚠️ 未找到 pnpm尝试使用 npm...${NC}"
PACKAGE_MANAGER="npm"
else
echo -e "${GREEN}✅ pnpm 版本: $(pnpm -v)${NC}"
PACKAGE_MANAGER="pnpm"
fi
echo ""
echo -e "${GREEN}开始编译...${NC}"
echo ""
# ============================================
# 第一部分:编译后端
# ============================================
echo -e "${BLUE}🏗️ 编译后端项目...${NC}"
echo ""
cd "${BACKEND_DIR}"
# 清理并编译
echo -e "${YELLOW}📦 清理并编译后端...${NC}"
mvn clean package -DskipTests -Dmaven.javadoc.skip=true -q
if [ $? -eq 0 ]; then
echo -e "${GREEN}✅ 后端编译成功!${NC}"
# 查找生成的 JAR 文件
JAR_FILE=$(find "${BACKEND_DIR}/yudao-server/target" -name "yudao-server-*.jar" 2>/dev/null | head -1)
if [ -n "$JAR_FILE" ]; then
echo -e "${GREEN}📁 生成的 JAR 文件: ${JAR_FILE}${NC}"
# 复制到部署目录
mkdir -p "${BACKEND_OUTPUT_DIR}"
cp "${JAR_FILE}" "${BACKEND_OUTPUT_DIR}/"
echo -e "${GREEN}📁 已复制到部署目录: ${BACKEND_OUTPUT_DIR}/$(basename $JAR_FILE)${NC}"
fi
else
echo -e "${RED}❌ 后端编译失败!${NC}"
exit 1
fi
echo ""
# ============================================
# 第二部分:编译前端
# ============================================
echo -e "${BLUE}🎨 编译前端项目...${NC}"
echo ""
cd "${FRONTEND_DIR}"
# 检查依赖是否已安装
if [ ! -d "node_modules" ]; then
echo -e "${YELLOW}📥 安装前端依赖...${NC}"
$PACKAGE_MANAGER install
if [ $? -ne 0 ]; then
echo -e "${RED}❌ 前端依赖安装失败!${NC}"
exit 1
fi
fi
# 清理并编译生产版本
echo -e "${YELLOW}📦 编译前端生产版本...${NC}"
$PACKAGE_MANAGER build:prod
if [ $? -eq 0 ]; then
echo -e "${GREEN}✅ 前端编译成功!${NC}"
# 复制到部署目录
mkdir -p "${FRONTEND_OUTPUT_DIR}"
# 复制编译产物
if [ -d "dist" ]; then
rm -rf "${FRONTEND_OUTPUT_DIR}/dist"
cp -r "dist" "${FRONTEND_OUTPUT_DIR}/"
echo -e "${GREEN}📁 已复制到部署目录: ${FRONTEND_OUTPUT_DIR}/dist${NC}"
fi
else
echo -e "${RED}❌ 前端编译失败!${NC}"
exit 1
fi
echo ""
# ============================================
# 完成
# ============================================
echo -e "${GREEN}========================================${NC}"
echo -e "${GREEN}🎉 编译完成!${NC}"
echo -e "${GREEN}========================================${NC}"
echo ""
echo -e "${YELLOW}部署文件位置:${NC}"
echo -e " - 后端: ${BACKEND_OUTPUT_DIR}/"
echo -e " - 前端: ${FRONTEND_OUTPUT_DIR}/dist/"
echo ""
echo -e "${YELLOW}下一步:${NC}"
echo -e " 1. 部署后端 JAR 文件"
echo -e " 2. 部署前端静态文件"
echo -e " 3. 配置 Nginx"
echo ""

27
deploy/.gitignore vendored Normal file
View File

@ -0,0 +1,27 @@
# 数据目录
data/
# 日志文件
*.log
logs/
# Docker 镜像(体积大,不纳入版本控制)
xlcp-images/
# 临时文件
*.tmp
*.swp
*.swo
# IDE
.idea/
.vscode/
*.iml
# OS
.DS_Store
Thumbs.db
# 环境变量
.env.local
.env.*.local

View File

@ -0,0 +1,297 @@
# XL监狱综合管理平台 - 部署前检查清单
## 🖥️ 远程服务器架构检查
由于无法直接SSH连接,请手动运行以下命令检查远程服务器架构:
```bash
ssh root@192.168.10.150 "uname -m && cat /etc/os-release && docker --version && docker compose version"
```
### 预期输出示例:
**x86_64 架构 (最常见)**:
```
x86_64
NAME="CentOS Linux"
VERSION="7 (Core)"
Docker version 24.0.7
Docker Compose version v2.24.0
```
**ARM64 架构 (树莓派、ARM服务器)**:
```
aarch64
NAME="Ubuntu"
VERSION="22.04.3 LTS (Jammy Jellyfish)"
Docker version 24.0.7
Docker Compose version v2.24.0
```
## ✅ 部署方式选择
### 方式 A: 在线部署 (服务器网络良好)
**适用场景**:
- 服务器可以访问 Docker Hub
- 网络带宽充足
- 快速测试部署
**步骤**:
```bash
cd deploy
./scripts/deploy.sh
```
### 方式 B: 离线部署 (推荐生产环境) ⭐
**适用场景**:
- 服务器网络受限
- 需要离线部署
- 多服务器部署
- 网络速度慢
**步骤**:
#### 1. 本地打包镜像
```bash
cd deploy
./scripts/save-images.sh
```
这会创建 `images-archive/` 目录,包含:
- `xlcp-docker-images.tar.gz` (约 2-3GB)
- `upload.sh` (自动上传脚本)
- `README.md` (详细说明)
#### 2. 上传镜像到服务器
**方式 2.1: 使用自动脚本** (最简单)
```bash
cd images-archive
./upload.sh
```
**方式 2.2: 手动上传**
```bash
cd images-archive
# 使用 scp
scp xlcp-docker-images.tar.gz root@192.168.10.150:/projects/data/xlcp/
# 或使用 rsync
rsync -avz --progress xlcp-docker-images.tar.gz root@192.168.10.150:/projects/data/xlcp/
```
#### 3. 在服务器加载镜像
```bash
# SSH 到服务器
ssh root@192.168.10.150
# 进入目录
cd /projects/data/xlcp
# 加载镜像
docker load -i xlcp-docker-images.tar.gz
# 验证镜像
docker images | grep -E 'mysql|redis|nginx'
```
#### 4. 部署服务
```bash
# 确保部署文件已上传
cd /projects/data/xlcp
# 启动服务
docker compose up -d
# 查看状态
docker compose ps
```
## 📋 镜像兼容性说明
### ✅ 全平台支持
以下镜像在 **x86_64****ARM64** 上都支持:
| 镜像 | x86_64 | ARM64 | 说明 |
|------|--------|-------|------|
| mysql:8.0 | ✅ | ✅ | 官方支持双架构 |
| redis:7-alpine | ✅ | ✅ | 官方支持双架构 |
| nginx:1.25-alpine | ✅ | ✅ | 官方支持双架构 |
| node:20-alpine | ✅ | ✅ | 官方支持双架构 |
### ⚠️ 构建镜像
以下镜像仅在本地构建时使用,不会影响部署:
| 镜像 | 用途 | x86_64 | ARM64 |
|------|------|--------|-------|
| maven:3.9-eclipse-temurin-21 | 后端编译 | ✅ | ✅ |
| eclipse-temurin:21-jre-alpine | 后端运行 | ✅ | ✅ |
### 🔄 架构不兼容怎么办?
如果远程服务器架构与本地不同,有以下解决方案:
#### 方案 1: 在远程服务器直接构建 (推荐)
```bash
# 上传源代码到服务器
rsync -avz --exclude node_modules --exclude target \
../ root@192.168.10.150:/projects/data/xlcp/
# SSH 到服务器
ssh root@192.168.10.150
# 进入项目目录
cd /projects/data/xlcp
# 构建镜像
cd deploy
docker compose build
```
#### 方案 2: 使用 buildx 构建多架构镜像
```bash
# 启用 buildx
docker buildx create --name multiarch --use
# 构建并导出多架构镜像
docker buildx build --platform linux/amd64,linux/arm64 \
-t xlcp-backend \
--load \
-f docker/backend/Dockerfile \
../backend
```
#### 方案 3: 使用交叉编译 (高级)
需要配置 QEMU 等工具,比较复杂,不推荐。
## 🎯 快速决策树
```
检查服务器网络
|
├─ 可以访问 Docker Hub
| └─ 使用方式 A (在线部署)
|
└─ 无法访问或速度慢
|
├─ 架构相同 (都是 x86_64 或都是 ARM64)
| └─ 使用方式 B (离线部署)
|
└─ 架构不同
|
├─ 服务器性能好
| └─ 方案 1 (远程构建)
|
└─ 服务器性能差
└─ 找一台相同架构的机器做离线包
```
## 📝 实际操作示例
### 示例 1: 本地 Mac (ARM64) -> 远程 Linux (x86_64)
```bash
# 检查本地架构
uname -m
# 输出: arm64 (Apple Silicon)
# 检查远程架构
ssh root@192.168.10.150 "uname -m"
# 输出: x86_64
# 由于架构不同,选择在远程服务器构建
rsync -avz --exclude node_modules --exclude target \
/path/to/xlcp/ root@192.168.10.150:/projects/data/xlcp/
ssh root@192.168.10.150 'cd /projects/data/xlcp/deploy && docker compose up -d --build'
```
### 示例 2: 本地 Mac (x86_64) -> 远程 Linux (x86_64)
```bash
# 架构相同,可以使用离线部署
cd /path/to/xlcp/deploy
./scripts/save-images.sh
cd images-archive
./upload.sh
```
## 🆘 常见问题
### Q1: 如何快速查看服务器架构?
```bash
ssh root@192.168.10.150 "uname -m"
```
输出:
- `x86_64` = Intel/AMD 64位
- `aarch64` = ARM 64位
- `armv7l` = ARM 32位
### Q2: 镜像很大,上传需要多久?
取决于网络速度:
- 100Mbps: 约 3-5 分钟
- 10Mbps: 约 30-50 分钟
- 1Mbps: 约 5-8 小时
建议使用 rsync,支持断点续传。
### Q3: 上传中断了怎么办?
使用 rsync 的断点续传功能:
```bash
rsync -avz --partial --progress \
xlcp-docker-images.tar.gz root@192.168.10.150:/projects/data/xlcp/
```
### Q4: 服务器没有 Docker 怎么办?
先安装 Docker:
```bash
ssh root@192.168.10.150
# CentOS/RHEL
curl -fsSL https://get.docker.com | sh
systemctl start docker
systemctl enable docker
# Ubuntu/Debian
curl -fsSL https://get.docker.com | sh
systemctl start docker
systemctl enable docker
```
## ✅ 推荐的最佳实践
1. **开发环境**: 使用在线部署,快速迭代
2. **测试环境**: 使用离线部署,模拟生产
3. **生产环境**:
- 准备离线镜像包
- 多次测试部署流程
- 准备回滚方案
4. **多环境部署**: 建立镜像仓库 (Harbor/Registry)
## 📞 下一步
完成架构检查后,选择对应的部署方式:
- **在线部署**: 直接运行 `./scripts/deploy.sh`
- **离线部署**: 先运行 `./scripts/save-images.sh`
- **远程构建**: 先上传代码,再远程构建
需要帮助? 查看各脚本的帮助信息:
```bash
./scripts/save-images.sh --help
./scripts/deploy.sh --help
```

232
deploy/DEPLOYMENT_STATUS.md Normal file
View File

@ -0,0 +1,232 @@
# XL监狱综合管理平台 - 部署完成报告
## 📊 部署状态
### ✅ 已完成 (方案 A - 离线部署)
#### 步骤 1: 本地镜像打包 ✅
- 下载并打包了 6 个 Docker 镜像
- 文件: `xlcp-docker-images.tar.gz` (592MB)
- 完成时间: 约 15 分钟
#### 步骤 2: 上传镜像到服务器 ✅
- 目标服务器: `root@192.168.10.150`
- 部署目录: `/projects/data/xlcp`
- 上传时间: 约 1 分钟 (内网速度 ~10MB/s)
- 所有镜像已成功加载
#### 步骤 3: 启动基础服务 ✅
**运行中的服务:**
- ✅ MySQL 8.0 - 端口 3306 - 健康检查通过
- ✅ Redis 7 - 端口 6380 - 健康检查通过 (已自动调整端口避免冲突)
**服务器信息:**
- 架构: ARM64 (aarch64)
- 系统: openEuler 22.03 (LTS-SP4)
- Docker: v28.5.2
- Docker Compose: v2.40.3 (同时支持 docker-compose v1)
- 内存: 250GB 总计
- 磁盘: 62GB 可用
---
## ⚠️ 待完成
### 步骤 4: 构建并启动应用服务
由于应用需要在服务器上编译构建,还需要以下步骤:
#### 后端服务 (Spring Boot + Java 21)
**需要:**
1. 上传 backend 源代码
2. 在服务器上 Maven 编译
3. 构建 Docker 镜像
4. 启动容器
**预计时间:** 10-15 分钟
#### 前端服务 (Vue 3 + Node 20)
**需要:**
1. 上传 frontend 源代码
2. 在服务器上 pnpm 安装依赖
3. 构建 Vue 应用
4. 构建 Docker 镜像
5. 启动 Nginx 容器
**预计时间:** 5-10 分钟
---
## 🚀 完成部署的两种方式
### 方式 1: 使用远程构建脚本 (推荐) ⭐
**最简单,一键完成所有操作**
```bash
cd /Volumes/Dpan/github/xlcp/deploy
./scripts/remote-build.sh
```
**这个脚本会自动:**
1. 上传 backend 和 frontend 源代码
2. 在远程服务器编译构建
3. 启动所有服务
4. 健康检查
**注意:** 需要先修改脚本中的服务器地址为 `root@192.168.10.150`
---
### 方式 2: 手动分步执行
#### 2.1 上传源代码
```bash
# 上传 backend
rsync -avz --exclude node_modules --exclude target \
../backend/ root@192.168.10.150:/projects/data/xlcp/backend/
# 上传 frontend
rsync -avz --exclude node_modules --exclude 'dist*' \
../frontend/ root@192.168.10.150:/projects/data/xlcp/frontend/
```
#### 2.2 构建并启动服务
SSH 到服务器:
```bash
ssh root@192.168.10.150
cd /projects/data/xlcp
# 构建后端镜像
docker-compose build backend
# 构建前端镜像
docker-compose build frontend
# 启动所有服务
docker-compose up -d
# 查看状态
docker-compose ps
```
---
## 📝 验证部署
部署完成后,访问以下地址验证:
```bash
# 前端页面
curl http://192.168.10.150/
# 后端健康检查
curl http://192.168.10.150:48080/actuator/health
# 查看日志
ssh root@192.168.10.150 'cd /projects/data/xlcp && docker-compose logs -f'
```
---
## 🔧 管理命令
```bash
# SSH 到服务器
ssh root@192.168.10.150
# 进入项目目录
cd /projects/data/xlcp
# 查看服务状态
docker-compose ps
# 查看日志
docker-compose logs -f
# 重启服务
docker-compose restart backend frontend
# 停止所有服务
docker-compose stop
# 启动所有服务
docker-compose start
# 删除所有容器
docker-compose down
```
---
## 🎯 访问地址 (部署完成后)
- **前端页面**: http://192.168.10.150/
- **后端 API**: http://192.168.10.150:48080/admin-api/
- **健康检查**: http://192.168.10.150:48080/actuator/health
---
## ⚠️ 注意事项
1. **Redis 端口已调整**
- 原端口: 6379
- 新端口: 6380 (避免与现有服务冲突)
- 已自动更新 `.env` 配置
2. **首次部署需要构建**
- 后端 Java 编译需要 10-15 分钟
- 前端 Vue 构建需要 5-10 分钟
- 请耐心等待
3. **磁盘空间**
- 镜像文件: 约 2GB
- 构建缓存: 约 1GB
- 日志和数据: 随时间增长
4. **防火墙**
- 确保端口 80, 48080, 3306, 6380 已开放
- 或在内网访问
---
## 📞 下一步
**请选择:**
A. **一键完成部署** (推荐)
- 运行: `./scripts/remote-build.sh`
- 等待 10-30 分钟自动完成
B. **手动分步部署**
- 按照上述步骤手动执行
- 更可控,可以看到详细过程
C. **暂时停止**
- MySQL 和 Redis 已运行
- 可以稍后继续部署应用
---
## 📊 部署时间线
| 步骤 | 操作 | 耗时 | 状态 |
|------|------|------|------|
| 1 | 本地打包镜像 | 15 分钟 | ✅ 完成 |
| 2 | 上传镜像到服务器 | 1 分钟 | ✅ 完成 |
| 3 | 启动 MySQL/Redis | 1 分钟 | ✅ 完成 |
| 4 | 构建后端服务 | 10-15 分钟 | ⏳ 待完成 |
| 5 | 构建前端服务 | 5-10 分钟 | ⏳ 待完成 |
| **总计** | | **32-42 分钟** | **60% 完成** |
---
**当前进度: 60%**
✅ 基础设施已就绪
⏳ 应用服务待部署
*建议使用远程构建脚本一键完成剩余 40% 的工作*

393
deploy/DEPLOY_JAR.md Normal file
View File

@ -0,0 +1,393 @@
# XL监狱综合管理平台 - 生产部署包部署指南
## 📋 目录结构
```
deploy/
├── docker-compose.yml # Docker Compose 编排文件
├── config/
│ └── application-prod.yaml # 生产环境配置
├── docker/
│ └── backend/
│ ├── Dockerfile # 后端镜像构建(基于已编译的 JAR
│ └── .dockerignore
├── sql/
│ └── prison_schema.sql # 数据库初始化脚本
└── scripts/
├── build.sh # 本地镜像构建脚本
├── deploy.sh # 远程部署脚本(含源码构建)
├── deploy-jar-only.sh # 新增:仅部署已编译 JAR 包
├── init-db.sh # 数据库初始化脚本
└── save-images.sh # 基础镜像打包脚本
```
## 🎯 两种部署模式对比
| 部署模式 | 使用场景 | 是否需要源码 | 是否需要编译 | 构建位置 |
|---------|---------|------------|------------|---------|
| **源码构建** | 开发环境、有构建权限的环境 | ✅ 需要 | ✅ 需要 | Docker 容器内 |
| **JAR 包部署** | 生产环境、无构建权限的环境 | ❌ 不需要 | ❌ 不需要 | 本地已完成编译 |
---
## 📦 方式一JAR 包部署(推荐生产环境)
### 适用场景
- 生产服务器没有 Maven/Node.js 环境
- 希望快速部署,不想在服务器上编译
- 源码不对外开放,只交付编译产物
### 前置要求
1. **本地已完成编译**
```bash
# 后端编译
cd backend
mvn clean package -DskipTests
# 前端编译(如果使用 Docker 构建 Nginx 镜像)
cd frontend
pnpm install
pnpm build:prod
```
2. **服务器环境**
- Docker 20.10+
- Docker Compose 2.0+
- 至少 4GB 内存, 20GB 磁盘空间
### 部署步骤
#### 1. 本地构建 JAR 包镜像
```bash
cd /path/to/xlcp/deploy
# 使用专门的 JAR 包部署脚本
./scripts/deploy-jar-only.sh
```
这个脚本会:
- ✅ 检查后端 JAR 包是否存在(`backend/yudao-server/target/yudao-server.jar`
- ✅ 检查前端构建产物是否存在(`frontend/dist/`
- ✅ 使用 `docker/backend/Dockerfile.jar` 构建 Docker 镜像
- ✅ 上传镜像到远程服务器
- ✅ 上传必要的配置文件和 docker-compose.yml
- ✅ 在远程服务器启动服务
#### 2. 手动部署流程(如果不用脚本)
**2.1 本地构建镜像**
```bash
cd deploy
# 构建后端镜像(基于已编译的 JAR
docker build -f docker/backend/Dockerfile.jar -t xlcp-backend:latest ../backend
# 构建前端镜像(基于已编译的 dist
docker build -f docker/frontend/Dockerfile.dist -t xlcp-frontend:latest ../frontend
```
**2.2 导出镜像**
```bash
# 导出镜像为 tar 文件
docker save xlcp-backend xlcp-frontend | gzip > xlcp-images.tar.gz
```
**2.3 上传到服务器**
```bash
# 上传镜像文件
scp xlcp-images.tar.gz root@192.168.10.150:/projects/data/xlcp/
# 上传配置文件
rsync -avz \
--exclude 'node_modules' \
--exclude 'target' \
--exclude '.git' \
--exclude 'backend' \
--exclude 'frontend' \
./ root@192.168.10.150:/projects/data/xlcp/deploy/
```
**2.4 服务器端加载镜像**
```bash
# SSH 到服务器
ssh root@192.168.10.150
# 进入目录
cd /projects/data/xlcp
# 加载镜像
docker load -i xlcp-images.tar.gz
# 启动服务
cd deploy
docker compose up -d
```
#### 3. 验证部署
```bash
# 健康检查
curl http://192.168.10.150:48080/actuator/health
curl http://192.168.10.150/
# 查看日志
ssh root@192.168.10.150 'cd /projects/data/xlcp/deploy && docker compose logs -f'
```
---
## 🔨 方式二:源码构建部署(开发环境)
### 适用场景
- 开发环境
- 服务器有完整的构建环境Maven, Node.js
- 需要在服务器上实时修改代码并重新构建
### 部署步骤
#### 使用现有的 deploy.sh 脚本
```bash
cd deploy
# 默认部署到 root@192.168.10.150
./scripts/deploy.sh
# 或指定服务器
REMOTE_SERVER=root@192.168.10.150 ./scripts/deploy.sh
```
脚本会:
1. 上传源代码到服务器
2. 在服务器上使用 Docker 构建镜像
3. 启动所有服务
---
## 📂 文件说明
### 核心配置文件
- **docker-compose.yml**:服务编排文件,定义 MySQL、Redis、Backend、Frontend 服务
- **config/application-prod.yaml**生产环境配置数据库连接、Redis 配置等)
### Docker 镜像构建文件
- **docker/backend/Dockerfile**多阶段构建从源码编译Maven + Java 源码 → JAR → 镜像)
- **docker/backend/Dockerfile.jar**:直接使用已编译的 JAR 包JAR → 镜像)- **新增**
- **docker/frontend/Dockerfile**前端构建Node.js + Vue 源码 → dist → Nginx 镜像)
- **docker/frontend/Dockerfile.dist**:直接使用已编译的 distdist → Nginx 镜像)- **新增**
### 部署脚本
- **scripts/deploy.sh**:源码构建部署(上传源码 → 服务器构建)
- **scripts/deploy-jar-only.sh**JAR 包部署(本地构建镜像 → 上传镜像)- **新增**
- **scripts/save-images.sh**打包基础镜像MySQL, Redis, Nginx, Java
- **scripts/upload-to-150.sh**:上传镜像到 192.168.10.150
- **scripts/init-db.sh**:初始化数据库
---
## 🔍 部署流程详解
### JAR 包部署流程(推荐)
```
[本地] 编译 JAR 包
[本地] 构建 Docker 镜像(基于 JAR
[本地] 导出镜像为 tar 文件
[上传] 镜像文件 + 配置文件 → 服务器
[服务器] 加载镜像
[服务器] docker compose up -d
[完成] 服务运行
```
### 源码构建部署流程
```
[上传] 源代码 + 配置文件 → 服务器
[服务器] docker compose build在容器内编译
[服务器] docker compose up -d
[完成] 服务运行
```
---
## 🚀 快速命令参考
### JAR 包部署(推荐生产)
```bash
# 1. 本地编译
cd backend && mvn clean package -DskipTests
cd ../frontend && pnpm build:prod
# 2. 本地构建镜像
cd ../deploy
./scripts/deploy-jar-only.sh root@192.168.10.150
```
### 源码构建部署(开发环境)
```bash
# 直接部署(服务器上构建)
cd deploy
./scripts/deploy.sh root@192.168.10.150
```
### 服务管理
```bash
# 查看状态
ssh root@192.168.10.150 'cd /projects/data/xlcp/deploy && docker compose ps'
# 查看日志
ssh root@192.168.10.150 'cd /projects/data/xlcp/deploy && docker compose logs -f backend'
# 重启服务
ssh root@192.168.10.150 'cd /projects/data/xlcp/deploy && docker compose restart backend'
# 停止服务
ssh root@192.168.10.150 'cd /projects/data/xlcp/deploy && docker compose down'
# 更新服务(重新构建镜像)
docker compose build backend && docker compose up -d backend
```
---
## ⚠️ 注意事项
### 生产环境建议
1. **使用 JAR 包部署**,不要在服务器上编译
2. **修改默认密码**MySQL root、Redis
3. **配置防火墙**仅开放必要端口80, 443
4. **启用 HTTPS**,配置 SSL 证书
5. **定期备份数据**(数据库、上传文件)
6. **监控日志**,及时发现异常
### 磁盘空间管理
```bash
# 查看磁盘使用
docker system df
# 清理未使用的镜像
docker image prune -a
# 清理未使用的容器
docker container prune
# 清理未使用的卷
docker volume prune
# 全面清理(谨慎使用)
docker system prune -a --volumes
```
### 网络配置
如果服务器有防火墙,确保开放以下端口:
- **80**HTTP 访问(前端)
- **443**HTTPS 访问(前端,如果启用 SSL
- **48080**:后端 API可配置防火墙规则仅允许内网访问
```bash
firewall-cmd --permanent --add-port=80/tcp
firewall-cmd --permanent --add-port=443/tcp
firewall-cmd --permanent --add-port=48080/tcp
firewall-cmd --reload
```
---
## 📚 附录
### 环境变量说明
| 变量名 | 默认值 | 说明 |
|---------|---------|------|
| MYSQL_ROOT_PASSWORD | Prison2024!@ | MySQL root 密码 |
| MYSQL_DATABASE | prison | 数据库名称 |
| MYSQL_PORT | 3306 | MySQL 端口 |
| REDIS_PASSWORD | Prison2024!@ | Redis 密码 |
| REDIS_PORT | 6379 | Redis 端口 |
| BACKEND_PORT | 48080 | 后端服务端口 |
| FRONTEND_PORT | 80 | 前端服务端口 |
| SPRING_PROFILES_ACTIVE | prod | Spring 环境配置 |
| JAVA_OPTS | -Xms512m -Xmx1024m | JVM 参数 |
### 访问地址
部署完成后:
- **前端**http://192.168.10.150/
- **后端 API**http://192.168.10.150:48080/admin-api/
- **健康检查**http://192.168.10.150:48080/actuator/health
### 故障排查
#### 1. 后端服务无法启动
```bash
# 查看日志
docker compose logs backend
# 检查数据库连接
docker compose exec backend sh
curl http://mysql:3306
# 检查配置
docker compose exec backend cat /app/config/application-prod.yaml
```
#### 2. 前端页面无法访问
```bash
# 检查 Nginx 配置
docker compose exec frontend nginx -t
# 查看 Nginx 日志
docker compose logs frontend
# 检查静态文件
docker compose exec frontend ls -la /usr/share/nginx/html
```
#### 3. 数据库连接失败
```bash
# 检查 MySQL 容器
docker compose ps mysql
docker compose logs mysql
# 测试连接
docker compose exec mysql mysql -u root -pPrison2024!@ -e "SELECT 1"
```
---
## 🆘 获取帮助
- 查看部署脚本帮助:`./scripts/deploy-jar-only.sh --help`
- 查看项目文档:`/README.md`
- 查看后端配置:`/backend/README.md`
- 查看前端配置:`/frontend/README.md`

439
deploy/README.md Normal file
View File

@ -0,0 +1,439 @@
# XL监狱综合管理平台 - Docker 部署指南
## 📋 目录结构
```
deploy/
├── docker-compose.yml # Docker Compose 编排文件
├── .env # 环境变量配置
├── .gitignore # Git 忽略文件
├── config/
│ └── application-prod.yaml # 生产环境配置
├── data/ # 数据目录(自动创建)
│ ├── mysql/ # MySQL 数据文件
│ ├── redis/ # Redis 数据文件
│ └── upload/ # 上传文件
├── logs/ # 日志目录(自动创建)
│ ├── backend/ # 后端日志
│ └── nginx/ # Nginx 日志
├── docker/
│ └── frontend/
│ └── nginx.conf # Nginx 配置
├── sql/
│ └── prison_schema.sql # 数据库初始化脚本
└── scripts/
├── build.sh # 镜像构建脚本(已弃用)
├── deploy.sh # 远程部署脚本(已弃用)
├── init-db.sh # 数据库初始化脚本
└── init-permissions.sh # 权限初始化脚本
```
## 🚀 快速开始
### 前置要求
- Docker 20.10+
- Docker Compose 2.0+ (或 docker-compose 1.29+)
- 服务器至少 4GB 内存, 20GB 磁盘空间
- SSH 免密登录到目标服务器 (如果远程部署)
### 方式一: 本地部署
#### 1. 克隆项目
```bash
cd /path/to/xlcp
```
#### 2. 配置环境变量
编辑 `.env` 文件,根据需要修改配置:
```bash
vi deploy/.env
```
关键配置项:
- `MYSQL_ROOT_PASSWORD`: MySQL root 密码
- `REDIS_PASSWORD`: Redis 密码
- `BACKEND_PORT`: 后端服务端口 (默认 48080)
- `FRONTEND_PORT`: 前端服务端口 (默认 80)
#### 3. 构建镜像
```bash
cd deploy
./scripts/build.sh
```
#### 4. 启动服务
```bash
docker compose up -d
```
或使用 docker-compose:
```bash
docker-compose up -d
```
#### 5. 查看日志
```bash
# 查看所有服务日志
docker compose logs -f
# 查看特定服务日志
docker compose logs -f backend
docker compose logs -f frontend
docker compose logs -f mysql
docker compose logs -f redis
```
#### 6. 停止服务
```bash
docker compose down
```
#### 7. 完全清理
```bash
docker compose down -v # 同时删除数据卷
```
### 方式二: 远程部署 (推荐生产环境)
#### 1. 配置远程服务器信息
```bash
# 方式 1: 使用默认配置 (root@192.168.10.150)
cd deploy
./scripts/deploy.sh
# 方式 2: 自定义服务器
REMOTE_SERVER=user@your-server-ip ./scripts/deploy.sh
# 方式 3: 自定义部署目录
REMOTE_SERVER=root@192.168.10.150 REMOTE_DEPLOY_DIR=/projects/data/xlcp ./scripts/deploy.sh
```
#### 2. 部署流程
脚本会自动执行:
1. ✅ 检查 SSH 连接
2. ✅ 检查远程 Docker 环境
3. ✅ 创建远程目录结构
4. ✅ 上传部署文件
5. ✅ 启动所有容器
6. ✅ 健康检查
7. ✅ 显示访问信息
#### 3. 访问服务
部署完成后:
- 前端: http://192.168.10.150/
- 后端 API: http://192.168.10.150:48080/admin-api/
- 健康检查: http://192.168.10.150:48080/actuator/health
#### 4. 查看远程日志
```bash
ssh root@192.168.10.150
cd /projects/data/xlcp
docker compose logs -f
```
## 🔧 服务管理
### 查看服务状态
```bash
docker compose ps
```
### 重启单个服务
```bash
# 重启后端
docker compose restart backend
# 重启前端
docker compose restart frontend
# 重启 MySQL
docker compose restart mysql
```
### 进入容器
```bash
# 进入后端容器
docker compose exec backend sh
# 进入 MySQL 容器
docker compose exec mysql bash
# 进入 Redis 容器
docker compose exec redis sh
```
### 更新服务
```bash
# 1. 重新构建镜像
docker compose build backend frontend
# 2. 重启服务
docker compose up -d backend frontend
```
## 📊 数据库管理
### 初始化数据库
```bash
cd deploy
./scripts/init-db.sh
```
### 手动执行 SQL
```bash
# 进入 MySQL 容器
docker compose exec mysql bash
# 连接 MySQL
mysql -u root -pPrison2024!@ prison
# 执行 SQL
source /docker-entrypoint-initdb.d/01-prison_schema.sql
```
### 数据库备份
```bash
# 备份整个数据库
docker exec xlcp-mysql mysqldump -u root -pPrison2024!@ prison > prison_backup_$(date +%Y%m%d).sql
# 恢复数据库
docker exec -i xlcp-mysql mysql -u root -pPrison2024!@ prison < prison_backup_20250122.sql
```
### 查看数据库
```bash
docker exec xlcp-mysql mysql -u root -pPrison2024!@ prison -e "SHOW TABLES;"
```
## 🔍 故障排查
### 服务无法启动
1. 查看服务日志
```bash
docker compose logs backend
docker compose logs frontend
```
2. 检查端口占用
```bash
netstat -tlnp | grep -E '3306|6379|48080|80'
```
3. 检查磁盘空间
```bash
df -h
docker system df
```
### 健康检查失败
1. 检查后端服务是否启动
```bash
curl http://localhost:48080/actuator/health
```
2. 检查前端服务是否启动
```bash
curl http://localhost/
```
3. 查看详细日志
```bash
docker compose logs -f backend
```
### 数据库连接失败
1. 检查 MySQL 容器状态
```bash
docker compose ps mysql
docker compose logs mysql
```
2. 测试数据库连接
```bash
docker exec xlcp-mysql mysqladmin ping -h localhost -u root -pPrison2024!@
```
3. 检查配置文件
```bash
cat config/application-prod.yaml | grep datasource
```
### 前端页面无法访问
1. 检查 Nginx 配置
```bash
docker compose exec frontend nginx -t
```
2. 查看 Nginx 日志
```bash
docker compose logs frontend
```
3. 检查静态文件
```bash
docker compose exec frontend ls -la /usr/share/nginx/html
```
## 📈 监控和日志
### 实时监控
```bash
# 监控所有服务
docker compose logs -f
# 监控特定服务
docker compose logs -f backend
```
### 查看日志文件
```bash
# 后端日志 (Docker 内部)
docker compose exec backend cat /logs/yudao-server.log
# Nginx 日志
docker compose exec frontend tail -f /var/log/nginx/access.log
docker compose exec frontend tail -f /var/log/nginx/error.log
# MySQL 日志
docker compose exec mysql tail -f /var/log/mysql/error.log
```
### 资源监控
```bash
# 查看容器资源使用
docker stats
# 查看磁盘使用
docker system df
# 清理未使用的资源
docker system prune -a
```
## 🔒 安全建议
1. **修改默认密码**
- MySQL root 密码
- Redis 密码
2. **配置防火墙**
```bash
# 仅开放必要端口
firewall-cmd --permanent --add-port=48080/tcp
firewall-cmd --permanent --add-port=80/tcp
firewall-cmd --reload
```
3. **启用 HTTPS**
- 准备 SSL 证书
- 放置到 `deploy/docker/ssl/` 目录
- 修改 `nginx.conf` 配置
4. **定期备份数据**
- 数据库备份
- 上传文件备份
- 配置文件备份
## 📚 附录
### 环境变量说明
| 变量名 | 默认值 | 说明 |
|---------|---------|------|
| MYSQL_ROOT_PASSWORD | Prison2024!@ | MySQL root 密码 |
| MYSQL_DATABASE | prison | 数据库名称 |
| MYSQL_PORT | 3306 | MySQL 端口 |
| REDIS_PASSWORD | Prison2024!@ | Redis 密码 |
| REDIS_PORT | 6379 | Redis 端口 |
| BACKEND_PORT | 48080 | 后端服务端口 |
| FRONTEND_PORT | 80 | 前端服务端口 |
| SPRING_PROFILES_ACTIVE | prod | Spring 环境配置 |
| JAVA_OPTS | -Xms512m -Xmx1024m | JVM 参数 |
### 端口说明
| 服务 | 容器端口 | 宿主机端口 | 说明 |
|------|-----------|------------|------|
| MySQL | 3306 | 3306 | 数据库服务 |
| Redis | 6379 | 6379 | 缓存服务 |
| Backend | 48080 | 48080 | 后端 API 服务 |
| Frontend | 80 | 80 | 前端 Web 服务 |
### 常用命令
```bash
# 查看 Docker 版本
docker --version
docker compose version
# 查看容器列表
docker ps -a
# 查看镜像列表
docker images | grep xlcp
# 查看网络
docker network ls
docker network inspect xlcp_xlcp-network
# 查看数据卷
docker volume ls
docker volume inspect xlcp_mysql-data
```
## 🆘 获取帮助
- 查看部署脚本帮助: `./scripts/deploy.sh --help`
- 查看项目文档: `/README.md`
- 查看后端配置: `/backend/README.md`
- 查看前端配置: `/frontend/README.md`
## 📞 技术支持
如遇问题,请提供以下信息:
1. Docker 版本: `docker --version`
2. Docker Compose 版本: `docker compose version`
3. 操作系统版本: `cat /etc/os-release`
4. 错误日志: `docker compose logs`
5. 问题描述和复现步骤

View File

@ -0,0 +1,173 @@
spring:
application:
name: xlcp-server
# 排除微信自动配置(不需要社交登录功能)
autoconfigure:
exclude:
- com.binarywang.spring.starter.wxjava.mp.config.WxMpAutoConfiguration
# 数据源配置(使用新建的 MySQL 容器)
datasource:
dynamic:
datasource:
master:
# 使用 Docker 服务名连接 MySQL
url: jdbc:mysql://mysql:3306/xlcp?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&useUnicode=true&characterEncoding=utf8
username: root
password: ${MYSQL_ROOT_PASSWORD:-Xlcp@2025#Secure}
driver-class-name: com.mysql.cj.jdbc.Driver
slave:
# 从库配置(可选,如果不需要可以删除或保持与主库相同)
url: jdbc:mysql://mysql:3306/xlcp?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true&useUnicode=true&characterEncoding=utf8
username: root
password: ${MYSQL_ROOT_PASSWORD:-Xlcp@2025#Secure}
driver-class-name: com.mysql.cj.jdbc.Driver
hikari:
# 连接池配置
maximum-pool-size: 20
minimum-idle: 5
idle-timeout: 600000
connection-timeout: 30000
max-lifetime: 1800000
pool-name: PrisonHikariCP
# 连接健康检测
connection-test-query: SELECT 1
# Redis 配置(使用新建的 Redis 容器)
data:
redis:
host: redis
port: 6379
password: ${REDIS_PASSWORD:-Xlcp2025Redis}
database: 0
timeout: 10000ms
lettuce:
pool:
max-active: 20
max-wait: -1ms
max-idle: 10
min-idle: 0
shutdown-timeout: 100ms
# 文件上传配置
servlet:
multipart:
enabled: true
max-file-size: 100MB
max-request-size: 100MB
file-size-threshold: 2KB
# Jackson 配置
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
serialization:
write-dates-as-timestamps: false
# 服务器配置
server:
port: 48080
servlet:
context-path: /
compression:
enabled: true
mime-types: application/json,application/xml,text/html,text/xml,text/plain
error:
include-message: always
include-binding-errors: always
# 应用配置
app:
name: XL监狱综合管理平台
version: 1.0.0
# 验证码配置
captcha:
enabled: true
type: math
# 文件上传配置
upload:
path: ./data/upload
avatar-path: ./data/upload/avatar
cache-path: ./data/upload/cache
# XSS 过滤配置
security:
xss:
enabled: true
exclude-urls:
- /admin/ck/uploadImage
- /admin/oss/uploadToAliCloudV2
- /admin/oss/uploadToTencentCloudV2
# 日志配置
logging:
level:
root: INFO
cn.iocoder.yudao: DEBUG
cn.iocoder.yudao.module.prison: DEBUG
file:
name: logs/yudao-server.log
logback:
rollingpolicy:
max-history: 30
max-file-size: 100MB
total-size-cap: 3GB
# MyBatis Plus 配置
mybatis-plus:
mapper-locations: classpath*:mapper/**/*.xml
type-aliases-package: cn.iocoder.yudao.module.*.dal.dataobject
global-config:
db-config:
id-type: auto
logic-delete-field: deleted
logic-delete-value: 1
logic-not-delete-value: 0
banner: false
configuration:
map-underscore-to-camel-case: true
cache-enabled: false
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# Actuator 监控配置
management:
endpoints:
web:
exposure:
include: health,info,metrics,prometheus
base-path: /actuator
endpoint:
health:
show-details: always
metrics:
tags:
application: ${spring.application.name}
# LLM 配置(用于危险评估智能分析)
llm:
local:
base-url: ${LLM_BASE_URL:http://127.0.0.1:2100/v1}
api-key: ${LLM_API_KEY:}
model: ${LLM_MODEL:qwen3}
timeout-seconds: ${LLM_TIMEOUT:120}
# 微信公众号配置
wx:
mp:
app-id: wxf56b1542b9e85f8a
secret: 496379dcef1ba869e9234de8d598cfd3
config-storage:
type: RedisTemplate
key-prefix: wx
http-client-type: HttpClient
miniapp:
appid: wxc4598c446f8a9cb3
secret: 4a1a04e07f6a4a0751b39c3064a92c8b
config-storage:
type: RedisTemplate
key-prefix: wa
http-client-type: HttpClient

100
deploy/docker-compose.yml Normal file
View File

@ -0,0 +1,100 @@
name: xlcp
services:
# MySQL 数据库
mysql:
container_name: xlcp-mysql
image: mysql:8.0
user: "0:0"
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-Xlcp@2025#Secure}
MYSQL_DATABASE: ${MYSQL_DATABASE:-xlcp}
TZ: Asia/Shanghai
ports:
- "${MYSQL_PORT:-3306}:3306"
volumes:
- ./data/mysql:/var/lib/mysql
- ./sql/prison_schema.sql:/docker-entrypoint-initdb.d/01-prison_schema.sql:ro
command:
- --character-set-server=utf8mb4
- --collation-server=utf8mb4_unicode_ci
- --default-authentication-plugin=mysql_native_password
- --skip-name-resolve
networks:
- xlcp-network
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p${MYSQL_ROOT_PASSWORD:-Xlcp@2025#Secure}"]
interval: 10s
timeout: 5s
retries: 5
# Redis 缓存
redis:
container_name: xlcp-redis
image: redis:7-alpine
user: "0:0"
restart: unless-stopped
command: >
sh -c "redis-server --requirepass ${REDIS_PASSWORD:-Xlcp2025Redis} --appendonly yes --maxmemory 512mb --maxmemory-policy allkeys-lru"
ports:
- "${REDIS_PORT:-6380}:6379"
volumes:
- ./data/redis:/data
networks:
- xlcp-network
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 3s
retries: 5
# 后端服务
backend:
container_name: xlcp-backend
image: eclipse-temurin:21-jre-alpine
restart: unless-stopped
depends_on:
mysql:
condition: service_healthy
redis:
condition: service_healthy
ports:
- "${BACKEND_PORT:-48080}:48080"
environment:
SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES_ACTIVE:-prod}
JAVA_OPTS: ${JAVA_OPTS:--Xms512m -Xmx1024m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/logs}
TZ: Asia/Shanghai
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-Xlcp@2025#Secure}
REDIS_PASSWORD: ${REDIS_PASSWORD:-Xlcp2025Redis}
volumes:
- ./logs/backend:/logs
- ./data/upload:/app/data/upload
- ./config/application-prod.yaml:/app/application-prod.yaml:ro
- ./backend/yudao-server/target/yudao-server.jar:/app/app.jar:ro
working_dir: /app
networks:
- xlcp-network
command: ["sh", "-c", "apk add --no-cache curl tzdata >/dev/null 2>&1 && java $$JAVA_OPTS -jar /app/app.jar"]
# 前端 Nginx
frontend:
container_name: xlcp-frontend
image: nginx:1.25-alpine
user: "0:0"
restart: unless-stopped
ports:
- "${FRONTEND_PORT:-18080}:80"
- "${FRONTEND_HTTPS_PORT:-18443}:443"
volumes:
- ./docker/frontend/nginx.conf:/etc/nginx/nginx.conf:ro
- ./frontend/dist:/usr/share/nginx/html:ro
- ./logs/nginx:/var/log/nginx
- ./data/ssl:/etc/nginx/ssl
networks:
- xlcp-network
networks:
xlcp-network:
name: xlcp-network
driver: bridge

188
deploy/scripts/check-remote.sh Executable file
View File

@ -0,0 +1,188 @@
#!/bin/bash
# 远程服务器架构检查脚本
# 用法: ./check-remote.sh
REMOTE_SERVER="${1:-root@192.168.10.150}"
echo "========================================="
echo "检查远程服务器: $REMOTE_SERVER"
echo "========================================="
echo ""
# 检查 SSH 连接
echo "[1/8] 检查 SSH 连接..."
if ! ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no "$REMOTE_SERVER" "echo 'SSH 连接成功'" 2>/dev/null; then
echo "❌ SSH 连接失败"
echo ""
echo "请检查:"
echo " 1. SSH 免密登录是否配置?"
echo " 2. 是否可以手动: ssh $REMOTE_SERVER"
echo " 3. 远程服务器 IP 是否正确?"
exit 1
fi
echo "✅ SSH 连接正常"
echo ""
# 检查架构
echo "[2/8] 检查系统架构..."
ARCH=$(ssh "$REMOTE_SERVER" "uname -m" 2>/dev/null)
echo "✅ 系统架构: $ARCH"
# 映射到 Docker 平台
case "$ARCH" in
x86_64)
DOCKER_PLATFORM="linux/amd64"
echo "✅ Docker 平台: linux/amd64 (Intel/AMD 64位)"
;;
aarch64)
DOCKER_PLATFORM="linux/arm64"
echo "✅ Docker 平台: linux/arm64 (ARM 64位)"
;;
armv7l)
DOCKER_PLATFORM="linux/arm/v7"
echo "✅ Docker 平台: linux/arm/v7 (ARM 32位)"
;;
*)
DOCKER_PLATFORM="unknown"
echo "⚠️ 未知架构: $ARCH"
;;
esac
echo ""
# 检查操作系统
echo "[3/8] 检查操作系统..."
OS_INFO=$(ssh "$REMOTE_SERVER" "cat /etc/os-release | grep -E '^(NAME|VERSION)=' 2>/dev/null || cat /etc/issue" 2>/dev/null)
echo "✅ 操作系统:"
echo "$OS_INFO"
echo ""
# 检查 Docker
echo "[4/8] 检查 Docker..."
if DOCKER_VERSION=$(ssh "$REMOTE_SERVER" "docker --version" 2>/dev/null); then
echo "$DOCKER_VERSION"
# 检查 Docker 是否能拉取镜像
echo " 测试镜像拉取能力..."
if ssh "$REMOTE_SERVER" "docker pull hello-world:latest > /dev/null 2>&1"; then
echo " ✅ Docker Hub 访问正常"
CAN_PULL_IMAGES="yes"
else
echo " ❌ 无法拉取镜像 (可能需要配置镜像加速器)"
CAN_PULL_IMAGES="no"
fi
else
echo "❌ Docker 未安装"
echo ""
echo "请先安装 Docker:"
if echo "$OS_INFO" | grep -qi "ubuntu"; then
echo " curl -fsSL https://get.docker.com | sh"
elif echo "$OS_INFO" | grep -qi "centos"; then
echo " curl -fsSL https://get.docker.com | sh"
fi
exit 1
fi
echo ""
# 检查 Docker Compose
echo "[5/8] 检查 Docker Compose..."
if COMPOSE_VERSION=$(ssh "$REMOTE_SERVER" "docker compose version 2>/dev/null"); then
echo "$COMPOSE_VERSION (docker compose v2)"
elif COMPOSE_VERSION=$(ssh "$REMOTE_SERVER" "docker-compose --version" 2>/dev/null); then
echo "$COMPOSE_VERSION (docker-compose v1)"
else
echo "❌ Docker Compose 未安装"
echo ""
echo "请先安装 Docker Compose:"
echo " sudo curl -L \"https://github.com/docker/compose/releases/download/v2.24.0/docker-compose-\$(uname -s)-\$(uname -m)\" -o /usr/local/bin/docker-compose"
echo " sudo chmod +x /usr/local/bin/docker-compose"
exit 1
fi
echo ""
# 检查磁盘空间
echo "[6/8] 检查磁盘空间..."
DISK_INFO=$(ssh "$REMOTE_SERVER" "df -h / | tail -1")
echo "✅ 磁盘使用情况:"
echo "$DISK_INFO"
AVAILABLE=$(ssh "$REMOTE_SERVER" "df -BG / | tail -1 | awk '{print \$4}' | sed 's/G//'")
if [ "$AVAILABLE" -lt 10 ]; then
echo " ⚠️ 磁盘空间不足: ${AVAILABLE}G 可用,建议至少 20G"
else
echo " ✅ 磁盘空间充足"
fi
echo ""
# 检查内存
echo "[7/8] 检查内存..."
MEM_INFO=$(ssh "$REMOTE_SERVER" "free -h | grep Mem")
echo "✅ 内存使用情况:"
echo "$MEM_INFO"
TOTAL_MEM=$(ssh "$REMOTE_SERVER" "free -g | grep Mem | awk '{print \$2}'")
if [ "$TOTAL_MEM" -lt 2 ]; then
echo " ⚠️ 内存不足: ${TOTAL_MEM}G,建议至少 4G"
else
echo " ✅ 内存充足"
fi
echo ""
# 检查端口占用
echo "[8/8] 检查端口占用..."
PORTS_TO_CHECK="3306 6379 48080 80"
echo "检查端口: $PORTS_TO_CHECK"
PORTS_OCCUPIED=()
for port in $PORTS_TO_CHECK; do
if ssh "$REMOTE_SERVER" "netstat -tlnp 2>/dev/null | grep -E \":$port\s\" || ss -tlnp 2>/dev/null | grep -E \":$port\s\"" 2>/dev/null; then
echo " ⚠️ 端口 $port 已被占用"
PORTS_OCCUPIED+=("$port")
else
echo " ✅ 端口 $port 可用"
fi
done
if [ ${#PORTS_OCCUPIED[@]} -gt 0 ]; then
echo ""
echo "⚠️ 以下端口已被占用: ${PORTS_OCCUPIED[*]}"
echo "请修改 .env 文件中的端口配置或停止占用端口的服务"
fi
echo ""
echo "========================================="
echo "检查完成"
echo "========================================="
echo ""
echo "架构信息总结:"
echo " 系统架构: $ARCH"
echo " Docker 平台: $DOCKER_PLATFORM"
echo " Docker Hub: $([ "$CAN_PULL_IMAGES" = "yes" ] && echo "✅ 可访问" || echo "❌ 受限")"
echo ""
echo "Docker镜像下载建议:"
if [ "$CAN_PULL_IMAGES" = "yes" ]; then
echo " ✅ 服务器可以直接拉取镜像"
echo " 推荐使用: ./deploy.sh (在线部署)"
else
echo " ❌ 服务器无法直接拉取镜像"
echo " 推荐使用: ./save-images.sh (离线部署)"
fi
echo ""
echo "所需镜像及平台支持:"
echo " mysql:8.0 支持 $DOCKER_PLATFORM"
echo " redis:7-alpine 支持 $DOCKER_PLATFORM"
echo " nginx:1.25-alpine 支持 $DOCKER_PLATFORM"
echo " node:20-alpine 支持 $DOCKER_PLATFORM"
echo " eclipse-temurin:21-jre 支持 $DOCKER_PLATFORM"
echo ""
echo "下一步操作:"
if [ "$CAN_PULL_IMAGES" = "yes" ]; then
echo " 1. 在线部署: ./deploy.sh"
echo " 2. 或远程构建: ./remote-build.sh"
else
echo " 1. 本地打包: ./save-images.sh"
echo " 2. 上传镜像: cd images-archive && ./upload.sh"
echo " 3. 远程构建: ./remote-build.sh"
fi
echo ""

131
deploy/scripts/deploy-xlcp.sh Executable file
View File

@ -0,0 +1,131 @@
#!/bin/bash
set -e
PROJECT_NAME="xlcp"
REMOTE_SERVER="${1:-root@192.168.10.150}"
REMOTE_DEPLOY_DIR="${REMOTE_DEPLOY_DIR:-/projects/data/xlcp}"
LOCAL_DIR="$(cd "$(dirname "$0")" && pwd)/.."
log_info() { echo "[INFO] $1"; }
log_success() { echo "[SUCCESS] $1"; }
log_error() { echo "[ERROR] $1"; exit 1; }
check_files() {
log_info "检查必要文件..."
local files=(
"$LOCAL_DIR/backend/yudao-server/target/yudao-server.jar"
"$LOCAL_DIR/frontend/dist/index.html"
"$LOCAL_DIR/deploy/docker-compose.yml"
"$LOCAL_DIR/deploy/config/application-prod.yaml"
"$LOCAL_DIR/deploy/docker/frontend/nginx.conf"
"$LOCAL_DIR/deploy/sql/prison_schema.sql"
)
for file in "${files[@]}"; do
[ -f "$file" ] || log_error "文件不存在: $file"
done
log_success "所有必要文件存在"
}
upload_files() {
log_info "上传文件到 $REMOTE_SERVER..."
ssh "$REMOTE_SERVER" "mkdir -p $REMOTE_DEPLOY_DIR/{config,docker/frontend,sql,data,logs,backend/yudao-server/target}"
rsync -avz --delete --exclude '*.tar.gz' --exclude '.git' \
--exclude 'node_modules' --exclude 'target' \
"$LOCAL_DIR/deploy/" "$REMOTE_SERVER:$REMOTE_DEPLOY_DIR/deploy/"
rsync -avz --progress "$LOCAL_DIR/backend/yudao-server/target/yudao-server.jar" \
"$REMOTE_SERVER:$REMOTE_DEPLOY_DIR/backend/yudao-server/target/"
rsync -avz --delete --progress --exclude 'node_modules' \
"$LOCAL_DIR/frontend/dist/" "$REMOTE_SERVER:$REMOTE_DEPLOY_DIR/frontend/dist/"
log_success "文件上传完成"
}
init_remote_dirs() {
log_info "初始化远程目录..."
ssh "$REMOTE_SERVER" "cd $REMOTE_DEPLOY_DIR && mkdir -p data/{mysql,redis,upload} logs/{backend,nginx} ssl && chmod -R 777 data/ logs/"
log_success "远程目录初始化完成"
}
start_services() {
log_info "启动服务..."
ssh "$REMOTE_SERVER" "cd $REMOTE_DEPLOY_DIR/deploy && docker compose down -v 2>/dev/null; docker compose up -d"
log_success "服务启动命令已执行"
}
health_check() {
log_info "进行健康检查..."
local server_ip=$(echo "$REMOTE_SERVER" | cut -d'@' -f2)
for i in {1..30}; do
curl -f -s "http://$server_ip:48080/actuator/health" > /dev/null 2>&1 && { log_success "后端服务正常"; break; }
echo -n "."
sleep 2
done
log_info "检查前端..."
curl -f -s "http://$server_ip/" > /dev/null 2>&1 && log_success "前端服务正常" || log_warn "前端可能未启动"
}
show_access_info() {
local server_ip=$(echo "$REMOTE_SERVER" | cut -d'@' -f2)
echo ""
echo "========================================="
echo "部署成功!"
echo "========================================="
echo ""
echo "访问地址:"
echo " 前端: http://$server_ip/"
echo " 后端 API: http://$server_ip:48080/admin-api/"
echo " 健康检查: http://$server_ip:48080/actuator/health"
echo ""
echo "管理命令:"
echo " SSH: ssh $REMOTE_SERVER"
echo " 查看日志: ssh $REMOTE_SERVER 'cd $REMOTE_DEPLOY_DIR/deploy && docker compose logs -f'"
echo " 重启服务: ssh $REMOTE_SERVER 'cd $REMOTE_DEPLOY_DIR/deploy && docker compose restart'"
echo " 停止服务: ssh $REMOTE_SERVER 'cd $REMOTE_DEPLOY_DIR/deploy && docker compose down'"
echo ""
echo "数据目录: $REMOTE_DEPLOY_DIR/data"
echo "日志目录: $REMOTE_DEPLOY_DIR/logs"
}
show_help() {
echo "用法: $0 [remote_server]"
echo ""
echo "参数:"
echo " remote_server 远程服务器地址 (默认: root@192.168.10.150)"
echo ""
echo "环境变量:"
echo " REMOTE_DEPLOY_DIR 远程部署目录 (默认: /projects/data/xlcp)"
echo ""
echo "示例:"
echo " $0 # 部署到默认服务器"
echo " $0 root@192.168.10.150 # 部署到指定服务器"
echo " REMOTE_DEPLOY_DIR=/opt/xlcp $0 # 自定义部署目录"
echo ""
echo "检查文件:"
echo " backend/yudao-server/target/yudao-server.jar"
echo " frontend/dist/"
echo " deploy/docker-compose.yml"
echo " deploy/config/application-prod.yaml"
echo " deploy/docker/frontend/nginx.conf"
echo ""
}
main() {
echo "========================================="
echo "XL监狱综合管理平台 - 部署脚本"
echo "========================================="
[[ "$1" == "--help" || "$1" == "-h" ]] && { show_help; exit 0; }
log_info "项目: $PROJECT_NAME, 服务器: $REMOTE_SERVER"
log_info "部署目录: $REMOTE_DEPLOY_DIR"
echo ""
check_files
upload_files
init_remote_dirs
start_services
health_check
show_access_info
}
main "$@"

94
deploy/scripts/init-db.sh Executable file
View File

@ -0,0 +1,94 @@
#!/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 "${BLUE}[INFO]${NC} $1"
}
log_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# 检查 MySQL 连接
check_mysql() {
local mysql_host="${MYSQL_HOST:-localhost}"
local mysql_port="${MYSQL_PORT:-3306}"
local mysql_user="${MYSQL_USER:-root}"
local mysql_password="${MYSQL_PASSWORD:-Prison2024!@}"
log_info "检查 MySQL 连接..."
if ! docker exec xlcp-mysql mysqladmin ping -h "$mysql_host" -P "$mysql_port" -u "$mysql_user" -p"$mysql_password" 2>/dev/null; then
log_error "无法连接到 MySQL"
exit 1
fi
log_success "MySQL 连接正常"
}
# 初始化数据库
init_database() {
log_info "初始化数据库..."
docker exec -i xlcp-mysql mysql -u root -p"${MYSQL_PASSWORD:-Prison2024!@}" prison < ./sql/prison_schema.sql || {
log_error "数据库初始化失败"
exit 1
}
log_success "数据库初始化完成"
}
# 验证数据库
verify_database() {
log_info "验证数据库表结构..."
local table_count=$(docker exec xlcp-mysql mysql -u root -p"${MYSQL_PASSWORD:-Prison2024!@}" prison -e "SHOW TABLES;" 2>/dev/null | wc -l)
if [ "$table_count" -lt 10 ]; then
log_error "数据库表数量异常: $table_count"
exit 1
fi
log_success "数据库验证通过 (共 $table_count 张表)"
}
# 主函数
main() {
log_info "========================================="
log_info "XL监狱综合管理平台 - 数据库初始化"
log_info "========================================="
# 切换到脚本所在目录的上级目录deploy 目录)
cd "$(dirname "$0")/.."
# 检查 MySQL
check_mysql
# 初始化数据库
read -p "是否初始化数据库? (y/N): " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
init_database
fi
# 验证数据库
verify_database
log_success "========================================="
log_success "数据库初始化完成!"
log_success "========================================="
}
main "$@"

View File

@ -0,0 +1,48 @@
#!/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 "${BLUE}[INFO]${NC} $1"
}
log_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
# 初始化目录权限
init_permissions() {
log_info "初始化目录权限..."
# 创建必要的目录
mkdir -p data/{mysql,redis,upload}
mkdir -p logs/{backend,nginx}
# 设置目录权限为 777开发环境
# 这样任何容器用户都可以写入
chmod -R 777 data/ logs/
log_success "目录权限已设置"
}
# 检查是否在正确的目录
if [ ! -f "docker-compose.yml" ]; then
echo "错误: 请在 deploy 目录下运行此脚本"
exit 1
fi
init_permissions
log_success "初始化完成!"
log_info "目录结构:"
ls -la data/ logs/

View File

@ -0,0 +1,100 @@
#!/bin/bash
set -e
OUTPUT_DIR="./xlcp-images"
IMAGES=(
"mysql:8.0"
"redis:7-alpine"
"eclipse-temurin:21-jre-alpine"
"nginx:1.25-alpine"
)
log_info() { echo "[INFO] $1"; }
log_success() { echo "[SUCCESS] $1"; }
log_error() { echo "[ERROR] $1"; exit 1; }
mkdir -p "$OUTPUT_DIR"
log_info "拉取 Docker 镜像..."
for image in "${IMAGES[@]}"; do
log_info "拉取 $image..."
docker pull "$image"
done
log_info "导出镜像到 tar 文件..."
for image in "${IMAGES[@]}"; do
image_name=$(echo "$image" | tr ':/' '_')
log_info "导出 ${image} -> ${image_name}.tar"
docker save "$image" | gzip > "$OUTPUT_DIR/${image_name}.tar.gz"
done
cat > "$OUTPUT_DIR/upload.sh" << 'UPLOAD_EOF'
#!/bin/bash
set -e
REMOTE_SERVER="${1:-root@192.168.10.150}"
REMOTE_DIR="${REMOTE_DEPLOY_DIR:-/projects/data/xlcp}"
echo "上传镜像到 $REMOTE_SERVER..."
for file in *.tar.gz; do
echo "上传 $file..."
scp "$file" "$REMOTE_SERVER:$REMOTE_DIR/images-archive/"
done
echo "上传完成"
UPLOAD_EOF
chmod +x "$OUTPUT_DIR/upload.sh"
cat > "$OUTPUT_DIR/load.sh" << 'LOAD_EOF'
#!/bin/bash
set -e
for file in *.tar.gz; do
echo "加载 $file..."
docker load -i "$file"
done
echo "所有镜像加载完成"
docker images | grep -E "mysql|redis|eclipse-temurin|nginx"
LOAD_EOF
chmod +x "$OUTPUT_DIR/load.sh"
cat > "$OUTPUT_DIR/README.md" << 'README_EOF'
# XL监狱综合管理平台 - Docker 镜像包
## 镜像列表
| 镜像 | 用途 |
|------|------|
| mysql:8.0 | 数据库 |
| redis:7-alpine | 缓存 |
| eclipse-temurin:21-jre-alpine | 后端运行 |
| nginx:1.25-alpine | 前端服务 |
## 使用方法
### 1. 上传到服务器
```bash
cd images-archive
./upload.sh root@192.168.10.150
```
### 2. 在服务器加载镜像
```bash
ssh root@192.168.10.150
cd /projects/data/xlcp/images-archive
./load.sh
```
### 3. 验证镜像
```bash
docker images | grep -E "mysql|redis|eclipse-temurin|nginx"
```
README_EOF
log_success "镜像打包完成!"
echo ""
echo "镜像包位置: $OUTPUT_DIR/"
ls -lh "$OUTPUT_DIR/"
echo ""
echo "使用方法:"
echo " 1. 上传: cd $OUTPUT_DIR && ./upload.sh root@192.168.10.150"
echo " 2. 加载: ssh root@192.168.10.150 'cd /projects/data/xlcp/images-archive && ./load.sh'"

View File

@ -0,0 +1,290 @@
-- ============================================
-- XL监狱综合管理平台 - 数据库初始化脚本
-- 复用 RAGFlow MySQL 镜像创建独立数据库
-- ============================================
-- 创建数据库
-- ============================================
-- 罪犯信息表
-- ============================================
CREATE TABLE IF NOT EXISTS `prison_prisoner` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '罪犯ID',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
`prisoner_no` varchar(50) NOT NULL COMMENT '罪犯编号',
`name` varchar(50) NOT NULL COMMENT '姓名',
`gender` tinyint NOT NULL COMMENT '性别1-男 2-女',
`birthday` date DEFAULT NULL COMMENT '出生日期',
`id_card` varchar(18) DEFAULT NULL COMMENT '身份证号',
`ethnicity` varchar(50) DEFAULT NULL COMMENT '民族',
`native_place` varchar(100) DEFAULT NULL COMMENT '籍贯',
`education` tinyint DEFAULT NULL COMMENT '文化程度1-文盲 2-小学 3-初中 4-高中 5-中专 6-大专 7-本科 8-硕士 9-博士',
`occupation` varchar(50) DEFAULT NULL COMMENT '入狱前职业',
`address` varchar(500) DEFAULT NULL COMMENT '家庭住址',
`crime` varchar(200) NOT NULL COMMENT '罪名',
`sentence_years` int DEFAULT 0 COMMENT '刑期(年)',
`sentence_months` int DEFAULT 0 COMMENT '刑期(月)',
`life_imprisonment` tinyint DEFAULT 0 COMMENT '是否无期0-否 1-是',
`death_sentence_reprieve` tinyint DEFAULT 0 COMMENT '是否死缓0-否 1-是',
`court_name` varchar(100) DEFAULT NULL COMMENT '判决法院',
`judgment_date` date DEFAULT NULL COMMENT '判决日期',
`judgment_no` varchar(50) DEFAULT NULL COMMENT '判决书编号',
`original_sentence` varchar(100) DEFAULT NULL COMMENT '原判刑期',
`imprisonment_date` date DEFAULT NULL COMMENT '入狱日期',
`release_date` date DEFAULT NULL COMMENT '释放日期',
`release_type` tinyint DEFAULT 0 COMMENT '释放类型0-未知 1-刑满释放 2-假释 3-保外就医 4-减刑 5-暂予监外执行 6-特赦 7-死亡 8-其他',
`release_reason` varchar(500) DEFAULT NULL COMMENT '释放原因',
`photo` varchar(512) DEFAULT NULL COMMENT '照片URL',
`supervision_level` tinyint DEFAULT 2 COMMENT '监管等级1-严管 2-普管 3-宽管',
`risk_level` tinyint DEFAULT 1 COMMENT '风险等级1-低风险 2-中风险 3-高风险 4-极高风险',
`prison_area_id` bigint DEFAULT NULL COMMENT '监区ID',
`sub_area_id` bigint DEFAULT NULL COMMENT '分区ID',
`prison_cell_id` bigint DEFAULT NULL COMMENT '监室ID',
`marital_status` tinyint DEFAULT NULL COMMENT '婚姻状态1-未婚 2-已婚 3-离异 4-丧偶',
`crime_type` varchar(100) DEFAULT NULL COMMENT '罪名类型',
`sentence` varchar(100) DEFAULT NULL COMMENT '刑期',
`status` tinyint NOT NULL DEFAULT 1 COMMENT '状态1-在押 2-已释放 3-已死亡 4-假释',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
`creator` varchar(64) DEFAULT '' COMMENT '创建者',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updater` varchar(64) DEFAULT '' COMMENT '更新者',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_prisoner_no` (`prisoner_no`, `tenant_id`),
KEY `idx_name` (`name`),
KEY `idx_id_card` (`id_card`),
KEY `idx_status` (`status`)
) ENGINE=InnoDB COMMENT='罪犯信息表';
-- ============================================
-- 监区信息表
-- ============================================
CREATE TABLE IF NOT EXISTS `prison_area` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '监区ID',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
`name` varchar(50) NOT NULL COMMENT '监区名称',
`code` varchar(50) NOT NULL COMMENT '监区编码',
`type` tinyint DEFAULT NULL COMMENT '监区类型1-普通监区 2-严管监区 3-医院 4-禁闭室',
`capacity` int DEFAULT NULL COMMENT '容纳人数',
`current_count` int DEFAULT 0 COMMENT '当前人数',
`sort` int DEFAULT 0 COMMENT '排序',
`status` tinyint NOT NULL DEFAULT 1 COMMENT '状态1-启用 2-禁用',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
`creator` varchar(64) DEFAULT '' COMMENT '创建者',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updater` varchar(64) DEFAULT '' COMMENT '更新者',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_code` (`code`, `tenant_id`),
KEY `idx_sort` (`sort`)
) ENGINE=InnoDB COMMENT='监区信息表';
-- ============================================
-- 监室信息表
-- ============================================
CREATE TABLE IF NOT EXISTS `prison_cell` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '监室ID',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
`area_id` bigint NOT NULL COMMENT '所属监区ID',
`name` varchar(50) NOT NULL COMMENT '监室名称',
`code` varchar(50) NOT NULL COMMENT '监室编码',
`capacity` int DEFAULT NULL COMMENT '床位数量',
`current_count` int DEFAULT 0 COMMENT '当前人数',
`sort` int DEFAULT 0 COMMENT '排序',
`status` tinyint NOT NULL DEFAULT 1 COMMENT '状态1-启用 2-禁用',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
`creator` varchar(64) DEFAULT '' COMMENT '创建者',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updater` varchar(64) DEFAULT '' COMMENT '更新者',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_code` (`code`, `tenant_id`),
KEY `idx_area_id` (`area_id`)
) ENGINE=InnoDB COMMENT='监室信息表';
-- ============================================
-- 计分考核表
-- ============================================
CREATE TABLE IF NOT EXISTS `prison_score` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '记录ID',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
`prisoner_id` bigint NOT NULL COMMENT '罪犯ID',
`prisoner_no` varchar(50) NOT NULL COMMENT '罪犯编号',
`year` int NOT NULL COMMENT '考核年份',
`month` int NOT NULL COMMENT '考核月份',
`base_score` decimal(10,2) DEFAULT 0.00 COMMENT '基础分',
`reward_score` decimal(10,2) DEFAULT 0.00 COMMENT '加分',
`penalty_score` decimal(10,2) DEFAULT 0.00 COMMENT '扣分',
`total_score` decimal(10,2) DEFAULT 0.00 COMMENT '总分',
`level` tinyint DEFAULT NULL COMMENT '考核等级1-优秀 2-良好 3-合格 4-不合格',
`assessor_id` bigint DEFAULT NULL COMMENT '考核人ID',
`assessor_name` varchar(50) DEFAULT NULL COMMENT '考核人姓名',
`status` tinyint NOT NULL DEFAULT 1 COMMENT '状态1-待审核 2-已通过 3-已驳回',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
`creator` varchar(64) DEFAULT '' COMMENT '创建者',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updater` varchar(64) DEFAULT '' COMMENT '更新者',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`),
KEY `idx_prisoner_id` (`prisoner_id`),
KEY `idx_year_month` (`year`, `month`)
) ENGINE=InnoDB COMMENT='计分考核表';
-- ============================================
-- 危险评估表
-- ============================================
CREATE TABLE IF NOT EXISTS `prison_risk_assessment` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '评估ID',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
`prisoner_id` bigint NOT NULL COMMENT '罪犯ID',
`prisoner_no` varchar(50) NOT NULL COMMENT '罪犯编号',
`assessment_type` tinyint NOT NULL COMMENT '评估类型1-入狱评估 2-定期评估 3-专项评估',
`assessment_date` date NOT NULL COMMENT '评估日期',
`violence_score` decimal(10,2) DEFAULT 0.00 COMMENT '暴力倾向得分',
`escape_score` decimal(10,2) DEFAULT 0.00 COMMENT '脱逃倾向得分',
`suicide_score` decimal(10,2) DEFAULT 0.00 COMMENT '自杀倾向得分',
`total_score` decimal(10,2) DEFAULT 0.00 COMMENT '综合得分',
`risk_level` tinyint NOT NULL COMMENT '风险等级1-低风险 2-中风险 3-高风险 4-极高风险',
`risk_factors` varchar(500) DEFAULT NULL COMMENT '风险因素',
`suggestions` varchar(500) DEFAULT NULL COMMENT '管控建议',
`assessor_id` bigint DEFAULT NULL COMMENT '评估人ID',
`assessor_name` varchar(50) DEFAULT NULL COMMENT '评估人姓名',
`next_assessment_date` date DEFAULT NULL COMMENT '下次评估日期',
`status` tinyint NOT NULL DEFAULT 1 COMMENT '状态1-待审核 2-已通过',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
`creator` varchar(64) DEFAULT '' COMMENT '创建者',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updater` varchar(64) DEFAULT '' COMMENT '更新者',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`),
KEY `idx_prisoner_id` (`prisoner_id`),
KEY `idx_assessment_date` (`assessment_date`)
) ENGINE=InnoDB COMMENT='危险评估表';
-- ============================================
-- 消费记录表
-- ============================================
CREATE TABLE IF NOT EXISTS `prison_consumption` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '记录ID',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
`prisoner_id` bigint NOT NULL COMMENT '罪犯ID',
`prisoner_no` varchar(50) NOT NULL COMMENT '罪犯编号',
`type` tinyint NOT NULL COMMENT '类型1-存款 2-消费 3-转账',
`amount` decimal(12,2) NOT NULL COMMENT '金额',
`balance` decimal(12,2) DEFAULT 0.00 COMMENT '账户余额',
`goods_name` varchar(100) DEFAULT NULL COMMENT '商品名称',
`goods_count` int DEFAULT 1 COMMENT '商品数量',
`order_no` varchar(64) DEFAULT NULL COMMENT '订单号',
`trade_time` datetime NOT NULL COMMENT '交易时间',
`status` tinyint NOT NULL DEFAULT 1 COMMENT '状态1-成功 2-失败',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
`creator` varchar(64) DEFAULT '' COMMENT '创建者',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updater` varchar(64) DEFAULT '' COMMENT '更新者',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`),
KEY `idx_prisoner_id` (`prisoner_id`),
KEY `idx_trade_time` (`trade_time`),
KEY `idx_type` (`type`)
) ENGINE=InnoDB COMMENT='消费记录表';
-- ============================================
-- 问卷模板表
-- ============================================
CREATE TABLE IF NOT EXISTS `prison_questionnaire` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '问卷ID',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
`title` varchar(200) NOT NULL COMMENT '问卷标题',
`type` tinyint NOT NULL COMMENT '问卷类型1-心理测评 2-行为评估 3-满意度调查',
`description` varchar(500) DEFAULT NULL COMMENT '问卷说明',
`total_score` decimal(10,2) DEFAULT 100.00 COMMENT '总分',
`pass_score` decimal(10,2) DEFAULT 60.00 COMMENT '及格分',
`status` tinyint NOT NULL DEFAULT 1 COMMENT '状态1-草稿 2-已发布 3-已禁用',
`creator` varchar(64) DEFAULT '' COMMENT '创建者',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updater` varchar(64) DEFAULT '' COMMENT '更新者',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`),
KEY `idx_type` (`type`),
KEY `idx_status` (`status`)
) ENGINE=InnoDB COMMENT='问卷模板表';
-- ============================================
-- 问卷问题表
-- ============================================
CREATE TABLE IF NOT EXISTS `prison_question` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '问题ID',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
`questionnaire_id` bigint NOT NULL COMMENT '所属问卷ID',
`title` varchar(500) NOT NULL COMMENT '问题标题',
`type` tinyint NOT NULL COMMENT '问题类型1-单选 2-多选 3-填空 4-评分',
`options` text COMMENT '选项JSON[{label:"选项1",score:10},...]',
`score` decimal(10,2) DEFAULT 0.00 COMMENT '分值',
`sort` int DEFAULT 0 COMMENT '排序',
`is_required` bit(1) DEFAULT b'1' COMMENT '是否必答',
`creator` varchar(64) DEFAULT '' COMMENT '创建者',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updater` varchar(64) DEFAULT '' COMMENT '更新者',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`),
KEY `idx_questionnaire_id` (`questionnaire_id`)
) ENGINE=InnoDB COMMENT='问卷问题表';
-- ============================================
-- 问卷答题记录表
-- ============================================
CREATE TABLE IF NOT EXISTS `prison_questionnaire_record` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '记录ID',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
`questionnaire_id` bigint NOT NULL COMMENT '问卷ID',
`prisoner_id` bigint NOT NULL COMMENT '罪犯ID',
`prisoner_no` varchar(50) NOT NULL COMMENT '罪犯编号',
`total_score` decimal(10,2) DEFAULT 0.00 COMMENT '得分',
`pass_status` tinyint DEFAULT NULL COMMENT '是否及格1-及格 2-不及格',
`answer_time` datetime NOT NULL COMMENT '答题时间',
`status` tinyint NOT NULL DEFAULT 1 COMMENT '状态1-已完成 2-已过期',
`creator` varchar(64) DEFAULT '' COMMENT '创建者',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updater` varchar(64) DEFAULT '' COMMENT '更新者',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`),
KEY `idx_questionnaire_id` (`questionnaire_id`),
KEY `idx_prisoner_id` (`prisoner_id`)
) ENGINE=InnoDB COMMENT='问卷答题记录表';
-- ============================================
-- 罪犯监区变动记录表
-- ============================================
CREATE TABLE IF NOT EXISTS `prison_prisoner_area_log` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
`prisoner_id` bigint NOT NULL COMMENT '罪犯ID',
`from_area_id` bigint DEFAULT NULL COMMENT '原监区ID',
`from_cell_id` bigint DEFAULT NULL COMMENT '原监室ID',
`to_area_id` bigint NOT NULL COMMENT '新监区ID',
`to_cell_id` bigint NOT NULL COMMENT '新监室ID',
`change_type` varchar(20) NOT NULL COMMENT '变动类型:调监区、调监室、入监、出监',
`reason` varchar(500) DEFAULT NULL COMMENT '变动原因',
`approve_no` varchar(50) DEFAULT NULL COMMENT '批准文号',
`operate_by` bigint NOT NULL COMMENT '操作人ID',
`operate_name` varchar(50) DEFAULT NULL COMMENT '操作人姓名',
`operate_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '操作时间',
`creator` varchar(64) DEFAULT '' COMMENT '创建者',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updater` varchar(64) DEFAULT '' COMMENT '更新者',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
PRIMARY KEY (`id`),
KEY `idx_prisoner_id` (`prisoner_id`),
KEY `idx_operate_time` (`operate_time`)
) ENGINE=InnoDB COMMENT='罪犯监区变动记录表';

284
deploy/sql/quartz.sql Normal file

File diff suppressed because one or more lines are too long

4087
deploy/sql/ruoyi-vue-pro.sql Normal file

File diff suppressed because it is too large Load Diff

756
docs/DEPLOYMENT.md Normal file
View File

@ -0,0 +1,756 @@
# XL 监狱综合管理平台部署文档
## 1. 文档概述
本文档详细描述 XL 监狱综合管理平台在服务器 `root@192.168.10.150` 上的部署流程。该平台采用 Docker 容器化部署方式,包含 MySQL 数据库、Redis 缓存、Spring Boot 后端服务和 Nginx 前端服务。
### 1.1 系统架构
```
┌─────────────────────────────────────────────────────────────────────┐
│ 服务器 192.168.10.150 │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ┌───────────────────────────────────────────────────────────────┐ │
│ │ Docker 网络 (xlcp-network) │ │
│ │ │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌────────────────────────┐ │ │
│ │ │ MySQL 8 │ │ Redis 6 │ │ 后端服务 (Java) │ │ │
│ │ │ 端口:3306 │ │ 端口:6379 │ │ 端口:48080 │ │ │
│ │ │ │ │ │ │ │ │ │
│ │ └──────┬──────┘ └──────┬──────┘ └───────────┬────────────┘ │ │
│ │ │ │ │ │ │
│ │ └────────────────┼──────────────────────┘ │ │
│ │ │ │ │
│ │ ┌──────┴──────┐ │ │
│ │ │ Nginx │ │ │
│ │ │ 端口:8080 │ │ │
│ │ └──────┬──────┘ │ │
│ │ │ │ │
│ └──────────────────────────┼─────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ 外部用户访问入口 │
│ http://192.168.10.150:8080 │
│ │
└─────────────────────────────────────────────────────────────────────┘
```
### 1.2 端口分配
| 服务 | 端口 | 说明 |
|------|------|------|
| Nginx 前端 | 8080 | Web 访问入口 |
| Spring Boot 后端 | 48080 | API 服务端口 |
| MySQL | 3306 | 数据库服务 |
| Redis | 6379 | 缓存服务 |
### 1.3 环境要求
在开始部署之前,请确保目标服务器满足以下最低要求:
- **操作系统**: CentOS 7+ / Ubuntu 18+ / Rocky Linux 8+ / Debian 10+
- **CPU**: 最低 2 核,推荐 4 核或更多
- **内存**: 最低 4GB推荐 8GB 或更多
- **硬盘**: 最低 50GB 可用空间,推荐 100GB SSD
- **网络**: 具备互联网访问能力,用于下载 Docker 镜像
## 2. 服务器环境准备
### 2.1 安装 Docker
以下是在 CentOS/Rocky Linux 系统上安装 Docker 的步骤。如果您的服务器已安装 Docker请跳过此步骤。
```bash
# 1. 安装必要依赖
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
# 2. 添加 Docker 官方仓库
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# 3. 安装 Docker 引擎
sudo yum install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
# 4. 启动 Docker 服务
sudo systemctl start docker
# 5. 设置开机自启动
sudo systemctl enable docker
# 6. 验证安装
docker --version
docker compose version
```
对于 Ubuntu/Debian 系统,请使用以下命令:
```bash
# 1. 更新软件包索引
sudo apt-get update
# 2. 安装必要依赖
sudo apt-get install -y ca-certificates curl gnupg lsb-release
# 3. 添加 Docker 官方 GPG 密钥
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
# 4. 设置 Docker 仓库
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
# 5. 安装 Docker
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
# 6. 启动并设置开机自启动
sudo systemctl start docker
sudo systemctl enable docker
```
### 2.2 配置 Docker 镜像加速
为了加速 Docker 镜像的下载,建议配置国内镜像加速器。
```bash
# 创建 Docker 配置目录
sudo mkdir -p /etc/docker
# 配置镜像加速器
sudo tee /etc/docker/daemon.json <<-EOF
{
"registry-mirrors": [
"https://docker.mirrors.ustc.edu.cn",
"https://hub-mirror.c.163.com",
"https://registry.docker-cn.com"
],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m",
"max-file": "3"
},
"storage-driver": "overlay2"
}
EOF
# 重启 Docker 服务
sudo systemctl daemon-reload
sudo systemctl restart docker
# 验证配置
docker info | grep "Registry Mirrors"
```
### 2.3 安装 Git用于拉取代码
```bash
# CentOS/Rocky Linux
sudo yum install -y git
# Ubuntu/Debian
sudo apt-get install -y git
```
## 3. 项目部署
### 3.1 创建部署目录结构
在服务器上创建项目部署目录:
```bash
# 创建项目根目录
sudo mkdir -p /work/projects/xlcp
sudo mkdir -p /work/projects/xlcp/{backend,frontend,data/{mysql,redis},logs,sql}
# 设置目录所有者(请将 username 替换为实际用户名)
sudo chown -R $USER:$USER /work/projects/xlcp
# 进入项目目录
cd /work/projects/xlcp
```
目录结构说明:
```
/work/projects/xlcp/
├── backend/ # 后端服务目录
│ ├── config/ # 配置文件目录
│ └── Dockerfile # Docker 构建文件
├── frontend/ # 前端服务目录
│ ├── dist/ # 前端构建产物
│ └── nginx.conf # Nginx 配置文件
├── data/ # 数据持久化目录
│ ├── mysql/ # MySQL 数据文件
│ └── redis/ # Redis 数据文件
├── logs/ # 日志目录
│ ├── backend/ # 后端日志
│ └── nginx/ # Nginx 日志
├── sql/ # SQL 初始化脚本
├── docker-compose.yml # Docker Compose 配置
└── README.md # 部署文档
```
### 3.2 获取项目代码
您可以通过以下两种方式之一获取项目代码:
**方式一:从 Git 仓库克隆**
```bash
cd /work/projects/xlcp
git clone <your-repository-url> ./source
```
**方式二:从本地复制**
在您的开发机器上执行以下命令,将项目复制到服务器:
```bash
# 复制整个项目到服务器
scp -r /Volumes/Dpan/github/xlcp root@192.168.10.150:/work/projects/xlcp/source
# 或者只复制必要文件
scp -r /Volumes/Dpan/github/xlcp/backend root@192.168.10.150:/work/projects/xlcp/
scp -r /Volumes/Dpan/github/xlcp/frontend/dist root@192.168.10.150:/work/projects/xlcp/frontend/
scp -r /Volumes/Dpan/github/xlcp/backend/sql/mysql/*.sql root@192.168.10.150:/work/projects/xlcp/sql/
```
### 3.3 复制配置文件
将预先准备好的配置文件复制到服务器:
```bash
# 复制 Docker Compose 配置
cp deploy/docker-compose.yml /work/projects/xlcp/
# 复制后端配置
cp deploy/config/application-prod.yaml /work/projects/xlcp/backend/config/
# 复制后端 Dockerfile
cp deploy/docker/backend/Dockerfile /work/projects/xlcp/backend/
# 复制前端 Nginx 配置
cp deploy/docker/frontend/nginx.conf /work/projects/xlcp/frontend/
# 复制 SQL 初始化脚本
cp backend/sql/mysql/*.sql /work/projects/xlcp/sql/
```
### 3.4 编译后端项目
在有 Maven 环境的机器上编译后端项目:
```bash
cd /Volumes/Dpan/github/xlcp/backend
# 清理并打包(跳过测试)
mvn clean package -DskipTests -Dmaven.javadoc.skip=true
# 构建完成后jar 包位于以下位置
ls -lh yudao-server/target/yudao-server.jar
```
将编译好的 jar 包复制到服务器:
```bash
scp yudao-server/target/yudao-server.jar root@192.168.10.150:/work/projects/xlcp/backend/
```
### 3.5 构建前端项目
在有 Node.js 环境的机器上构建前端:
```bash
cd /Volumes/Dpan/github/xlcp/frontend
# 安装依赖
pnpm install
# 生产环境构建
pnpm build:prod
# 构建完成后,构建产物在 dist 目录
ls -lh dist/
```
将构建产物复制到服务器:
```bash
scp -r dist/* root@192.168.10.150:/work/projects/xlcp/frontend/
```
## 4. 配置文件说明
### 4.1 Docker Compose 配置
主要配置项说明:
```yaml
version: "3.8"
services:
# MySQL 数据库服务
mysql:
image: mysql:8.0 # 使用 MySQL 8.0 镜像
container_name: xlcp-mysql # 容器名称
restart: unless-stopped # 异常退出后自动重启
environment:
MYSQL_ROOT_PASSWORD: Prison2024!@ # root 用户密码
MYSQL_DATABASE: prison # 数据库名称
volumes:
- ./data/mysql:/var/lib/mysql # 数据持久化
- ./sql:/docker-entrypoint-initdb.d:ro # 初始化脚本
ports:
- "3306:3306" # 端口映射
deploy:
resources:
limits:
memory: 2G # 内存限制
# Redis 缓存服务
redis:
image: redis:6.2-alpine
container_name: xlcp-redis
command: redis-server --requirepass Redis2024!@ # 设置密码
volumes:
- ./data/redis:/data
deploy:
resources:
limits:
memory: 512M
# 后端服务
backend:
build:
context: ./backend
dockerfile: Dockerfile
container_name: xlcp-backend
environment:
SPRING_PROFILES_ACTIVE: prod # 生产环境配置
JAVA_OPTS: -Xms512m -Xmx1024m # JVM 内存配置
volumes:
- ./backend/config:/app/config:ro # 配置文件挂载
- ./logs/backend:/app/logs # 日志目录挂载
depends_on:
mysql:
condition: service_healthy # 等待 MySQL 健康检查通过
redis:
condition: service_healthy # 等待 Redis 健康检查通过
# 前端服务
frontend:
image: nginx:alpine
container_name: xlcp-frontend
volumes:
- ./frontend/dist:/usr/share/nginx/html:ro # 前端静态文件
- ./frontend/nginx.conf:/etc/nginx/nginx.conf:ro
- ./logs/nginx:/var/log/nginx # Nginx 日志
```
### 4.2 后端生产配置
配置文件位置:`backend/config/application-prod.yaml`
主要配置项:
```yaml
spring:
datasource:
dynamic:
datasource:
master:
url: jdbc:mysql://mysql:3306/prison?useSSL=false&serverTimezone=Asia/Shanghai...
username: root
password: Prison2024!@
data:
redis:
host: redis # 使用 Docker 网络中的服务名
port: 6379
password: Redis2024!@
server:
port: 48080 # 后端服务端口
logging:
level:
cn.iocoder.yudao: DEBUG
```
**重要说明**:在 Docker 环境中,使用 Docker Compose 定义的服务名(如 `mysql``redis`)作为主机名,而非 IP 地址。
### 4.3 Nginx 配置
配置文件位置:`frontend/nginx.conf`
主要功能:
- 静态文件服务
- API 请求代理到后端服务
- Gzip 压缩
- 缓存配置
- 安全头配置
```nginx
upstream backend {
server backend:48080; # 后端服务地址
keepalive 32;
}
server {
listen 80;
# 前端路由支持
location / {
try_files $uri $uri/ /index.html;
}
# API 代理
location /prod-api/ {
proxy_pass http://backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
```
## 5. 部署执行
### 5.1 启动服务
```bash
cd /work/projects/xlcp
# 启动所有服务(后台运行)
docker compose up -d
# 查看启动状态
docker compose ps
# 查看服务日志
docker compose logs -f
```
### 5.2 验证部署
执行以下命令验证各服务是否正常运行:
```bash
# 1. 检查 MySQL
docker exec -it xlcp-mysql mysql -uroot -pPrison2024!@ -e "SHOW DATABASES;"
# 预期输出应包含 prison 数据库
# 2. 检查 Redis
docker exec -it xlcp-redis redis-cli -a Redis2024!@ ping
# 预期输出PONG
# 3. 检查后端健康状态
curl http://localhost:48080/actuator/health/
# 预期输出:{"status":"UP"}
# 4. 检查前端访问
curl -I http://localhost:8080/
# 预期输出HTTP/1.1 200 OK
```
### 5.3 查看日志
```bash
# 查看后端日志
docker logs xlcp-backend
tail -f /work/projects/xlcp/logs/backend/yudao-server.log
# 查看 Nginx 日志
docker logs xlcp-frontend
tail -f /work/projects/xlcp/logs/nginx/access.log
tail -f /work/projects/xlcp/logs/nginx/error.log
```
## 6. 访问地址
部署完成后,系统可通过以下地址访问:
| 服务 | 地址 | 说明 |
|------|------|------|
| 前端页面 | http://192.168.10.150:8080 | 监狱管理系统 Web 界面 |
| 后端 API | http://192.168.10.150:48080 | 后端服务接口 |
| 健康检查 | http://192.168.10.150:48080/actuator/health | 服务健康状态 |
| MySQL | 192.168.10.150:3306 | 数据库连接 |
| Redis | 192.168.10.150:6379 | 缓存服务 |
## 7. 运维管理
### 7.1 服务管理命令
```bash
# 启动所有服务
docker compose start
# 停止所有服务
docker compose stop
# 重启所有服务
docker compose restart
# 重启单个服务
docker compose restart backend
docker compose restart frontend
# 查看服务状态
docker compose ps
# 查看服务资源使用
docker stats
# 进入容器内部
docker exec -it xlcp-backend /bin/sh
docker exec -it xlcp-mysql mysql -uroot -pPrison2024!@
docker exec -it xlcp-redis redis-cli -a Redis2024!@
```
### 7.2 日志管理
```bash
# 查看所有服务日志
docker compose logs
# 查看指定服务日志
docker compose logs backend
docker compose logs frontend
docker compose logs mysql
docker compose logs redis
# 实时查看日志
docker compose logs -f
# 查看最近 100 行日志
docker logs --tail 100 xlcp-backend
```
### 7.3 数据备份
```bash
# 备份 MySQL 数据库
BACKUP_DIR=/work/projects/xlcp/backup
mkdir -p $BACKUP_DIR
BACKUP_DATE=$(date +%Y%m%d_%H%M%S)
docker exec xlcp-mysql mysqldump -uroot -pPrison2024!@ prison > $BACKUP_DIR/prison_$BACKUP_DATE.sql
# 压缩备份文件
gzip $BACKUP_DIR/prison_$BACKUP_DATE.sql
# 查看备份文件
ls -lh $BACKUP_DIR/
# 备份 Redis 数据
docker exec xlcp-redis redis-cli -a Redis2024!@ BGSAVE
docker cp xlcp-redis:/data/dump.rdb $BACKUP_DIR/redis_$BACKUP_DATE.rdb
```
### 7.4 版本更新
```bash
# 1. 停止当前服务
cd /work/projects/xlcp
docker compose down
# 2. 备份重要数据
cp -r data data.backup.$(date +%Y%m%d)
# 3. 更新代码
cd source
git pull
# 4. 重新编译
cd ../backend
mvn clean package -DskipTests
cd ../frontend
pnpm install && pnpm build:prod
# 5. 更新构建产物
cp -r dist/* ../frontend/
cp target/*.jar ../backend/
# 6. 重新构建镜像并启动
cd ..
docker compose build --no-cache
docker compose up -d
# 7. 验证部署
curl http://localhost:48080/actuator/health/
```
## 8. 常见问题排查
### 8.1 后端无法连接数据库
```bash
# 检查 MySQL 容器状态
docker ps | grep mysql
# 检查 MySQL 日志
docker logs xlcp-mysql
# 检查 MySQL 健康状态
docker exec xlcp-mysql mysqladmin -uroot -pPrison2024!@ ping
# 检查网络连接
docker exec xlcp-backend ping mysql
# 常见原因及解决方案:
# 1. MySQL 容器未启动 → docker compose restart mysql
# 2. 密码错误 → 检查 application-prod.yaml 配置
# 3. 网络问题 → 检查 Docker 网络状态
```
### 8.2 前端 502 错误
```bash
# 检查后端服务状态
docker ps | grep backend
# 检查后端健康状态
curl http://localhost:48080/actuator/health/
# 检查后端日志
docker logs xlcp-backend
# 检查 Nginx 配置
docker exec xlcp-frontend cat /etc/nginx/nginx.conf
# 测试后端连通性
docker exec xlcp-frontend curl http://backend:48080/actuator/health/
```
### 8.3 内存不足
```bash
# 检查容器资源使用情况
docker stats
# 调整 JVM 内存配置,编辑 docker-compose.yml
environment:
JAVA_OPTS: -Xms256m -Xmx512m
# 重新启动服务
docker compose restart backend
```
### 8.4 端口冲突
```bash
# 检查端口占用
netstat -tlnp | grep 8080
netstat -tlnp | grep 48080
# 如果端口被占用,可以修改 docker-compose.yml 中的端口映射
ports:
- "8081:80" # 改为 8081 端口
```
### 8.5 数据丢失
```bash
# 检查数据卷挂载
docker volume ls
# 检查数据目录权限
ls -la /work/projects/xlcp/data/
# 恢复数据(从备份)
gunzip -k /work/projects/xlcp/backup/prison_20240115.sql.gz
docker exec -i xlcp-mysql mysql -uroot -pPrison2024!@ prison < /work/projects/xlcp/backup/prison_20240115.sql
```
## 9. 安全加固建议
### 9.1 修改默认密码
生产环境中,请务必修改默认密码:
```yaml
# MySQL
MYSQL_ROOT_PASSWORD: YourStrongPassword123!@
# Redis
command: redis-server --requirepass YourStrongRedisPassword456!@
# 修改 application-prod.yaml 中的数据库密码
password: YourStrongPassword123!@
```
### 9.2 配置防火墙
```bash
# 只开放必要端口CentOS
firewall-cmd --permanent --add-port=8080/tcp
firewall-cmd --permanent --add-port=48080/tcp
firewall-cmd --reload
# 只开放必要端口Ubuntu
sudo ufw allow 8080/tcp
sudo ufw allow 48080/tcp
sudo ufw enable
```
### 9.3 启用 HTTPS推荐
建议使用 Nginx 反向代理并配置 SSL 证书:
```nginx
server {
listen 443 ssl http2;
server_name your-domain.com;
ssl_certificate /etc/nginx/ssl/cert.pem;
ssl_certificate_key /etc/nginx/ssl/key.pem;
ssl_protocols TLSv1.2 TLSv1.3;
# 其他配置...
}
server {
listen 80;
server_name your-domain.com;
return 301 https://$server_name$request_uri;
}
```
### 9.4 定期安全更新
```bash
# 更新系统软件包
sudo yum update -y # CentOS
sudo apt-get update && sudo apt-get upgrade -y # Ubuntu
# 更新 Docker
sudo yum update docker-ce # CentOS
sudo apt-get update && sudo apt-get install docker-ce # Ubuntu
```
### 9.5 监控与告警
建议配置以下监控:
- **服务监控**: 使用 Prometheus + Grafana 监控容器状态
- **日志监控**: 使用 ELK Stack 收集和分析日志
- **告警通知**: 配置邮件或企业微信告警通知
## 10. 联系与支持
如果在部署过程中遇到问题,请:
1. 查看本文档的常见问题排查章节
2. 检查各服务的日志文件
3. 联系系统管理员获取支持
---
**文档版本**: 1.0.0
**最后更新**: 2026年1月21日
**适用系统**: XL 监狱综合管理平台 v1.0

@ -1 +1 @@
Subproject commit 883c5fdb633714c7c49e93324a26d3a2e426ca1b
Subproject commit 3b3604073d9623917dcf47a1adaf337b394b6dcd

57
images-archive/upload.sh Executable file
View File

@ -0,0 +1,57 @@
#!/bin/bash
set -e
REMOTE_SERVER="root@192.168.10.150"
REMOTE_DIR="/projects/data/xlcp"
ARCHIVE_FILE="xlcp-docker-images.tar.gz"
echo "========================================="
echo "上传并加载 Docker 镜像到 192.168.10.150"
echo "========================================="
echo ""
echo "目标服务器: $REMOTE_SERVER"
echo "镜像文件: $ARCHIVE_FILE"
echo "文件大小: $(du -h $ARCHIVE_FILE | cut -f1)"
echo ""
# 创建远程目录
echo "[1/4] 创建远程目录..."
ssh "$REMOTE_SERVER" "mkdir -p $REMOTE_DIR"
echo "✅ 目录创建完成"
echo ""
# 上传镜像
echo "[2/4] 上传镜像到远程服务器..."
rsync -avz --progress "$ARCHIVE_FILE" "$REMOTE_SERVER:$REMOTE_DIR/"
echo ""
echo "✅ 上传完成"
echo ""
# 加载镜像
echo "[3/4] 在远程服务器加载镜像..."
ssh "$REMOTE_SERVER" << ENDSSH
cd $REMOTE_DIR
echo "解压并加载镜像..."
docker load -i "$ARCHIVE_FILE"
echo "✅ 镜像加载完成"
echo ""
echo "清理镜像文件..."
rm "$ARCHIVE_FILE"
echo "✅ 清理完成"
ENDSSH
echo ""
# 显示镜像列表
echo "[4/4] 显示远程服务器镜像列表..."
ssh "$REMOTE_SERVER" "docker images | grep -E 'mysql|redis|nginx|maven|eclipse-temurin|node'"
echo ""
echo "========================================="
echo "镜像上传和加载完成!"
echo "========================================="
echo ""
echo "下一步操作:"
echo " 运行部署脚本: cd .. && ./deploy-to-150.sh"
echo ""