diff --git a/backend/scripts/compare-databases.cjs b/backend/scripts/compare-databases.cjs new file mode 100644 index 00000000..e07d5986 --- /dev/null +++ b/backend/scripts/compare-databases.cjs @@ -0,0 +1,200 @@ +/** + * 对比本地数据库和RDS数据库的差异 + */ + +const { Client } = require('pg'); + +// 本地数据库配置 +const localConfig = { + host: 'localhost', + port: 5432, + database: 'ai_clinical_research', + user: 'postgres', + password: 'postgres123', +}; + +// RDS数据库配置(测试环境) +const rdsConfig = { + host: 'pgm-2zex1m2y3r23hdn5xo.pg.rds.aliyuncs.com', // 外网地址 + port: 5432, + database: 'ai_clinical_research_test', + user: 'airesearch', + password: 'Xibahe@fengzhibo117', + connectionTimeoutMillis: 30000, +}; + +async function getSchemas(client) { + const result = await client.query(` + SELECT schema_name + FROM information_schema.schemata + WHERE schema_name NOT IN ('pg_catalog', 'information_schema', 'pg_toast', 'pg_temp_1', 'pg_toast_temp_1') + ORDER BY schema_name + `); + return result.rows.map(r => r.schema_name); +} + +async function getTables(client) { + const result = await client.query(` + SELECT table_schema, table_name + FROM information_schema.tables + WHERE table_type = 'BASE TABLE' + AND table_schema NOT IN ('pg_catalog', 'information_schema') + ORDER BY table_schema, table_name + `); + return result.rows.map(r => `${r.table_schema}.${r.table_name}`); +} + +async function getExtensions(client) { + const result = await client.query(` + SELECT extname, extversion FROM pg_extension ORDER BY extname + `); + return result.rows; +} + +async function main() { + console.log('=' .repeat(60)); + console.log('数据库对比工具'); + console.log('=' .repeat(60)); + + // 连接本地数据库 + console.log('\n[1] 连接本地数据库...'); + const localClient = new Client(localConfig); + try { + await localClient.connect(); + console.log('✅ 本地数据库连接成功'); + } catch (err) { + console.log('❌ 本地数据库连接失败:', err.message); + return; + } + + // 连接RDS数据库 + console.log('\n[2] 连接RDS数据库...'); + const rdsClient = new Client(rdsConfig); + try { + await rdsClient.connect(); + console.log('✅ RDS数据库连接成功'); + } catch (err) { + console.log('❌ RDS数据库连接失败:', err.message); + await localClient.end(); + return; + } + + try { + // 对比 Extensions + console.log('\n' + '=' .repeat(60)); + console.log('📦 Extensions 对比'); + console.log('=' .repeat(60)); + + const localExtensions = await getExtensions(localClient); + const rdsExtensions = await getExtensions(rdsClient); + + console.log('\n本地 Extensions:'); + localExtensions.forEach(e => console.log(` - ${e.extname} (${e.extversion})`)); + + console.log('\nRDS Extensions:'); + rdsExtensions.forEach(e => console.log(` - ${e.extname} (${e.extversion})`)); + + // 对比 Schemas + console.log('\n' + '=' .repeat(60)); + console.log('📁 Schema 对比'); + console.log('=' .repeat(60)); + + const localSchemas = await getSchemas(localClient); + const rdsSchemas = await getSchemas(rdsClient); + + const schemasOnlyInLocal = localSchemas.filter(s => !rdsSchemas.includes(s)); + const schemasOnlyInRds = rdsSchemas.filter(s => !localSchemas.includes(s)); + const commonSchemas = localSchemas.filter(s => rdsSchemas.includes(s)); + + console.log(`\n共同 Schemas (${commonSchemas.length}个):`); + commonSchemas.forEach(s => console.log(` ✅ ${s}`)); + + if (schemasOnlyInLocal.length > 0) { + console.log(`\n⚠️ 仅在本地存在的 Schemas (${schemasOnlyInLocal.length}个):`); + schemasOnlyInLocal.forEach(s => console.log(` 🔴 ${s}`)); + } + + if (schemasOnlyInRds.length > 0) { + console.log(`\n仅在RDS存在的 Schemas (${schemasOnlyInRds.length}个):`); + schemasOnlyInRds.forEach(s => console.log(` 🟡 ${s}`)); + } + + // 对比 Tables + console.log('\n' + '=' .repeat(60)); + console.log('📊 Table 对比'); + console.log('=' .repeat(60)); + + const localTables = await getTables(localClient); + const rdsTables = await getTables(rdsClient); + + const tablesOnlyInLocal = localTables.filter(t => !rdsTables.includes(t)); + const tablesOnlyInRds = rdsTables.filter(t => !localTables.includes(t)); + + console.log(`\n本地表总数: ${localTables.length}`); + console.log(`RDS表总数: ${rdsTables.length}`); + + if (tablesOnlyInLocal.length > 0) { + console.log(`\n⚠️ 仅在本地存在的表 (${tablesOnlyInLocal.length}个) - 需要同步到RDS:`); + tablesOnlyInLocal.forEach(t => console.log(` 🔴 ${t}`)); + } else { + console.log('\n✅ 没有仅在本地存在的表'); + } + + if (tablesOnlyInRds.length > 0) { + console.log(`\n仅在RDS存在的表 (${tablesOnlyInRds.length}个):`); + tablesOnlyInRds.forEach(t => console.log(` 🟡 ${t}`)); + } + + // 检查关键表的字段差异 + console.log('\n' + '=' .repeat(60)); + console.log('🔍 关键表字段检查'); + console.log('=' .repeat(60)); + + // 检查 prompt_templates 表的 knowledge_config 字段 + const checkColumn = async (client, schema, table, column) => { + const result = await client.query(` + SELECT column_name, data_type + FROM information_schema.columns + WHERE table_schema = $1 AND table_name = $2 AND column_name = $3 + `, [schema, table, column]); + return result.rows.length > 0; + }; + + const localHasKnowledgeConfig = await checkColumn(localClient, 'capability_schema', 'prompt_templates', 'knowledge_config'); + const rdsHasKnowledgeConfig = await checkColumn(rdsClient, 'capability_schema', 'prompt_templates', 'knowledge_config'); + + console.log('\ncapability_schema.prompt_templates.knowledge_config:'); + console.log(` 本地: ${localHasKnowledgeConfig ? '✅ 存在' : '❌ 不存在'}`); + console.log(` RDS: ${rdsHasKnowledgeConfig ? '✅ 存在' : '❌ 不存在'}`); + + // 总结 + console.log('\n' + '=' .repeat(60)); + console.log('📋 同步建议'); + console.log('=' .repeat(60)); + + const needSync = schemasOnlyInLocal.length > 0 || tablesOnlyInLocal.length > 0 || (localHasKnowledgeConfig && !rdsHasKnowledgeConfig); + + if (needSync) { + console.log('\n⚠️ 需要同步以下内容到RDS:'); + if (schemasOnlyInLocal.length > 0) { + console.log(` - ${schemasOnlyInLocal.length} 个 Schema`); + } + if (tablesOnlyInLocal.length > 0) { + console.log(` - ${tablesOnlyInLocal.length} 个表`); + } + if (localHasKnowledgeConfig && !rdsHasKnowledgeConfig) { + console.log(' - prompt_templates.knowledge_config 字段'); + } + console.log('\n建议执行: npx prisma migrate deploy'); + } else { + console.log('\n✅ 数据库结构已同步,无需迁移'); + } + + } finally { + await localClient.end(); + await rdsClient.end(); + console.log('\n数据库连接已关闭'); + } +} + +main().catch(console.error); diff --git a/docs/00-系统总体设计/00-系统当前状态与开发指南.md b/docs/00-系统总体设计/00-系统当前状态与开发指南.md index 82865b75..3df39477 100644 --- a/docs/00-系统总体设计/00-系统当前状态与开发指南.md +++ b/docs/00-系统总体设计/00-系统当前状态与开发指南.md @@ -1,10 +1,11 @@ # AIclinicalresearch 系统当前状态与开发指南 -> **文档版本:** v4.5 +> **文档版本:** v4.6 > **创建日期:** 2025-11-28 > **维护者:** 开发团队 -> **最后更新:** 2026-01-28 +> **最后更新:** 2026-02-02 > **🎉 重大里程碑:** +> - **2026-02-02:REDCap 生产环境部署完成!** ECS + RDS + HTTPS + 域名全部配置完成 > - **2026-01-28:Prompt 知识库集成完成!** Prompt 可动态引用系统知识库内容 > - **2026-01-27:系统知识库管理功能完成!** 运营管理端新增知识库管理+文档上传下载 > - **2026-01-25:Protocol Agent MVP完整交付!** 一键生成研究方案+Word导出 @@ -12,14 +13,15 @@ > - **2026-01-22:OSS 存储集成完成!** 阿里云 OSS 正式接入平台基础层 > - **2026-01-21:成功替换 Dify!** PKB 模块完全使用自研 pgvector RAG 引擎 > -> **最新进展(Prompt 知识库集成 2026-01-28):** -> - ✅ **PromptService 增强**:支持 FULL/RAG 两种知识库注入模式 -> - ✅ **配置界面**:Prompt 编辑器右侧面板配置知识库增强 -> - ✅ **测试渲染**:预览知识库注入效果 -> - ✅ **发布即生效**:发布后业务端立即使用知识库增强 -> - ✅ **Bug 修复**:配置保存、发布按钮、缓存清除等问题 +> **最新进展(REDCap 生产环境部署 2026-02-02):** +> - ✅ **ECS 服务器配置**:Docker CE 26.1.3 + Docker Compose v2.27.0 +> - ✅ **RDS MySQL 配置**:redcap_prod 数据库 + utf8mb4 字符集 +> - ✅ **REDCap 15.8.0 部署**:Docker 容器化部署,数据库初始化完成 +> - ✅ **HTTPS 配置**:Nginx 反向代理 + 阿里云 SSL 证书 +> - ✅ **域名配置**:https://redcap.xunzhengyixue.com/ 正式上线 > > **部署状态:** ✅ 生产环境运行中 | 公网地址:http://8.140.53.236/ +> **REDCap 状态:** ✅ 生产环境运行中 | 地址:https://redcap.xunzhengyixue.com/ > **文档目的:** 快速了解系统当前状态,为新AI助手提供上下文 --- @@ -56,7 +58,7 @@ | **PKB** | 个人知识库 | RAG问答、私人文献库 | ⭐⭐⭐ | 🎉 **Dify已替换!自研RAG上线(95%)** | P1 | | **ASL** | AI智能文献 | 文献筛选、Meta分析、证据图谱 | ⭐⭐⭐⭐⭐ | 🎉 **智能检索MVP完成(60%)** - DeepSearch集成 | **P0** | | **DC** | 数据清洗整理 | ETL + 医学NER(百万行级数据) | ⭐⭐⭐⭐⭐ | ✅ **Tool B完成 + Tool C 99%(异步架构+性能优化-99%+多指标转换+7大功能)** | **P0** | -| **IIT** | IIT Manager Agent | AI驱动IIT研究助手 - 智能质控+REDCap集成 | ⭐⭐⭐⭐⭐ | 🎉 **Phase 1.5完成(60%)- AI对话+REDCap数据集成** | **P0** | +| **IIT** | IIT Manager Agent | AI驱动IIT研究助手 - 智能质控+REDCap集成 | ⭐⭐⭐⭐⭐ | 🎉 **Phase 2.0(65%)- AI对话+REDCap生产环境部署完成** | **P0** | | **SSA** | 智能统计分析 | 队列/预测模型/RCT分析 | ⭐⭐⭐⭐⭐ | 📋 规划中 | P2 | | **ST** | 统计分析工具 | 100+轻量化统计工具 | ⭐⭐⭐⭐ | 📋 规划中 | P2 | | **RVW** | 稿件审查系统 | 方法学评估、审稿流程、Word导出 | ⭐⭐⭐⭐ | ✅ **开发完成(95%)** | P3 | @@ -811,6 +813,15 @@ data: [DONE]\n\n - ✅ **代码设计完成**:RedcapAdapter、WebhookController、SyncManager - ✅ **REDCap文档体系**:部署手册、问题排查、API对接指南 +**REDCap生产环境部署完成**(2026-02-02):✅ **100%** +- ✅ **ECS服务器**:阿里云 ecs.u2a-c1m2.large(2核4GB),公网IP:39.105.153.58 +- ✅ **RDS MySQL**:MySQL 8.0(2核4GB),数据库:redcap_prod +- ✅ **Docker部署**:Docker CE 26.1.3 + Docker Compose v2.27.0 +- ✅ **HTTPS配置**:Nginx反向代理 + 阿里云免费SSL证书 +- ✅ **域名上线**:https://redcap.xunzhengyixue.com/ +- ✅ **管理员账户**:已创建,可正常登录 +- ✅ **完整文档**:部署方案 + 信息记录 + 问题排查手册 + **Day 1 技术验证**: ```bash # 数据库CRUD测试 - 全部通过 ✅ diff --git a/docs/03-业务模块/Redcap/01-部署与配置/14-REDCap_ECS生产环境部署方案.md b/docs/03-业务模块/Redcap/01-部署与配置/14-REDCap_ECS生产环境部署方案.md new file mode 100644 index 00000000..62512827 --- /dev/null +++ b/docs/03-业务模块/Redcap/01-部署与配置/14-REDCap_ECS生产环境部署方案.md @@ -0,0 +1,621 @@ +# REDCap 阿里云 ECS 生产环境部署方案 + +**版本:** v1.0 +**创建日期:** 2026-02-02 +**适用环境:** 阿里云 ECS + RDS MySQL 8.0 +**REDCap版本:** 15.8.0 +**状态:** 📋 待执行 + +--- + +## 📋 部署概览 + +### 目标架构 + +``` +┌─────────────────────────────────────────────────────────────┐ +│ 阿里云生产环境架构 │ +├─────────────────────────────────────────────────────────────┤ +│ │ +│ ┌──────────────────────────────────────────────────────┐ │ +│ │ 公网访问层 │ │ +│ │ 公网IP: 39.105.153.58:80/443 │ │ +│ └──────────────────────────────────────────────────────┘ │ +│ ↓ │ +│ ┌──────────────────────────────────────────────────────┐ │ +│ │ ECS 服务器 (launch-advisor-20260108) │ │ +│ │ ├── Docker Engine │ │ +│ │ └── REDCap 容器 │ │ +│ │ ├── Apache 2.4 + PHP 8.1 │ │ +│ │ └── REDCap 15.8.0 │ │ +│ │ 私网IP: 172.17.173.82 │ │ +│ └──────────────────────────────────────────────────────┘ │ +│ ↓ VPC内网 │ +│ ┌──────────────────────────────────────────────────────┐ │ +│ │ RDS MySQL 8.0 (rm-2ze9587199003517c) │ │ +│ │ ├── 2核 4GB │ │ +│ │ ├── 数据库: redcap_prod │ │ +│ │ └── 用户: redcap_user │ │ +│ │ 内网地址: rm-2ze9587199003517c.mysql.rds.aliyuncs.com │ +│ └──────────────────────────────────────────────────────┘ │ +│ │ +└─────────────────────────────────────────────────────────────┘ +``` + +### 资源清单 + +| 资源 | 规格 | 状态 | 备注 | +|------|------|------|------| +| ECS 服务器 | 2核 4GB | ✅ 已购买 | launch-advisor-20260108 | +| RDS MySQL | 2核 4GB,MySQL 8.0 | ✅ 已购买 | rm-2ze9587199003517c | +| 公网IP | 39.105.153.58 | ✅ 已分配 | 需配置安全组 | +| 域名 | 待配置 | ⏳ 可选 | 建议使用域名+SSL | + +--- + +## 🚀 部署步骤 + +### 阶段1:ECS 服务器初始化 + +#### 1.1 SSH 连接到 ECS + +```bash +# 方式1:使用阿里云控制台"远程连接" +# 方式2:本地 SSH 连接 +ssh root@39.105.153.58 +``` + +#### 1.2 更新系统 + +```bash +# 更新系统包 +sudo yum update -y + +# 安装常用工具 +sudo yum install -y git curl wget vim +``` + +#### 1.3 安装 Docker + +```bash +# 安装 Docker +sudo yum install -y docker + +# 启动 Docker 服务 +sudo systemctl start docker +sudo systemctl enable docker + +# 验证安装 +docker --version +# 预期输出: Docker version 20.x.x 或更高 + +# 添加当前用户到 docker 组(可选,避免每次 sudo) +sudo usermod -aG docker $USER +``` + +#### 1.4 安装 Docker Compose + +```bash +# 下载 Docker Compose +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 + +# 添加执行权限 +sudo chmod +x /usr/local/bin/docker-compose + +# 验证安装 +docker-compose --version +# 预期输出: Docker Compose version v2.24.0 +``` + +#### 1.5 创建工作目录 + +```bash +# 创建 REDCap 部署目录 +sudo mkdir -p /opt/redcap +sudo chown -R $USER:$USER /opt/redcap +cd /opt/redcap + +# 创建子目录 +mkdir -p config/{apache,php} +mkdir -p logs +``` + +--- + +### 阶段2:RDS MySQL 配置 + +#### 2.1 配置 RDS 白名单 + +**在阿里云 RDS 控制台操作:** + +1. 进入 RDS 实例详情页 +2. 左侧菜单 → "白名单与安全组" +3. 点击"修改",添加 ECS 私网 IP: + ``` + 172.17.173.82 + ``` +4. 保存 + +#### 2.2 获取 RDS 内网连接地址 + +**在 RDS 控制台 → "数据库连接" 页面获取:** + +``` +内网地址: rm-2ze9587199003517c.mysql.rds.aliyuncs.com +端口: 3306 +``` + +#### 2.3 创建 REDCap 数据库和用户 + +**方式1:使用阿里云 DMS 控制台** + +1. RDS 控制台 → 点击"登录数据库" +2. 执行以下 SQL: + +```sql +-- 创建数据库 +CREATE DATABASE redcap_prod +CHARACTER SET utf8mb4 +COLLATE utf8mb4_unicode_ci; + +-- 创建用户(使用强密码!) +CREATE USER 'redcap_user'@'172.17.173.%' +IDENTIFIED BY 'YOUR_STRONG_PASSWORD_32_CHARS_MIN'; + +-- 授予权限 +GRANT ALL PRIVILEGES ON redcap_prod.* TO 'redcap_user'@'172.17.173.%'; +FLUSH PRIVILEGES; + +-- 验证 +SHOW DATABASES; +SELECT User, Host FROM mysql.user WHERE User = 'redcap_user'; +``` + +**方式2:从 ECS 使用 mysql 客户端** + +```bash +# 安装 MySQL 客户端 +sudo yum install -y mysql + +# 连接 RDS(使用 root 账户) +mysql -h rm-2ze9587199003517c.mysql.rds.aliyuncs.com -u root -p + +# 执行上述 SQL +``` + +#### 2.4 记录数据库连接信息 + +``` +主机: rm-2ze9587199003517c.mysql.rds.aliyuncs.com +端口: 3306 +数据库: redcap_prod +用户名: redcap_user +密码: YOUR_STRONG_PASSWORD_32_CHARS_MIN +``` + +--- + +### 阶段3:准备 REDCap 文件 + +#### 3.1 上传 REDCap 源码 + +**方式1:使用 SCP 从本地上传** + +```powershell +# 在本地 Windows PowerShell 执行 +scp -r D:\MyCursor\Redcap\redcap15.8.0 root@39.105.153.58:/opt/redcap/ +``` + +**方式2:使用阿里云 OSS 中转** + +1. 上传 redcap15.8.0.zip 到 OSS +2. 在 ECS 下载: +```bash +cd /opt/redcap +wget https://your-bucket.oss-cn-beijing.aliyuncs.com/redcap15.8.0.zip +unzip redcap15.8.0.zip +``` + +#### 3.2 上传 Docker 配置文件 + +```powershell +# 在本地 Windows PowerShell 执行 +scp D:\MyCursor\Redcap\redcap-docker-dev\Dockerfile.redcap root@39.105.153.58:/opt/redcap/ +scp D:\MyCursor\Redcap\redcap-docker-dev\docker-entrypoint.sh root@39.105.153.58:/opt/redcap/ +scp D:\MyCursor\Redcap\redcap-docker-dev\config\php\php.ini root@39.105.153.58:/opt/redcap/config/php/ +scp D:\MyCursor\Redcap\redcap-docker-dev\config\apache\redcap.conf root@39.105.153.58:/opt/redcap/config/apache/ +``` + +#### 3.3 创建生产环境 database.php + +在 ECS 上创建: + +```bash +cat > /opt/redcap/config/database.php << 'EOF' + /opt/redcap/docker-compose.prod.yml << 'EOF' +# REDCap Docker Compose 配置 - 生产环境 +# 版本:v1.0 +# 日期:2026-02-02 +# 用途:阿里云 ECS + RDS MySQL 生产环境 + +version: '3.8' + +services: + # ========== REDCap Web服务 (Apache + PHP 8.1) ========== + redcap-web: + build: + context: . + dockerfile: Dockerfile.redcap + container_name: redcap-prod + restart: always + ports: + - "80:80" + # - "443:443" # HTTPS(配置SSL后启用) + volumes: + # REDCap源代码(只读) + - ./redcap15.8.0/redcap:/var/www/html/redcap:ro + + # 配置文件 + - ./config/apache/redcap.conf:/etc/apache2/sites-available/000-default.conf:ro + - ./config/php/php.ini:/usr/local/etc/php/php.ini:ro + - ./config/database.php:/var/www/html/redcap/database.php:ro + + # 持久化数据(可读写) + - redcap-edocs:/var/www/html/redcap/edocs + - redcap-modules:/var/www/html/redcap/modules + - redcap-temp:/var/www/html/redcap/temp + + # 日志 + - ./logs:/var/log/apache2 + environment: + TZ: Asia/Shanghai + # RDS 连接信息(用于健康检查) + REDCAP_DB_HOST: rm-2ze9587199003517c.mysql.rds.aliyuncs.com + REDCAP_DB_PORT: 3306 + REDCAP_DB_NAME: redcap_prod + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost/"] + interval: 30s + timeout: 10s + retries: 3 + logging: + driver: "json-file" + options: + max-size: "100m" + max-file: "3" + +# ========== 数据卷配置 ========== +volumes: + # REDCap上传文件(重要!需定期备份) + redcap-edocs: + name: redcap-edocs-prod + driver: local + + # External Modules + redcap-modules: + name: redcap-modules-prod + driver: local + + # 临时文件 + redcap-temp: + name: redcap-temp-prod + driver: local +EOF +``` + +#### 3.5 确保脚本有执行权限 + +```bash +chmod +x /opt/redcap/docker-entrypoint.sh +``` + +--- + +### 阶段4:配置安全组 + +#### 4.1 ECS 安全组规则 + +**在阿里云 ECS 控制台 → 安全组 配置:** + +| 规则方向 | 协议 | 端口 | 授权对象 | 说明 | +|---------|------|------|---------|------| +| 入方向 | TCP | 80 | 0.0.0.0/0 | HTTP访问 | +| 入方向 | TCP | 443 | 0.0.0.0/0 | HTTPS访问(可选) | +| 入方向 | TCP | 22 | 您的IP/32 | SSH管理(限制IP) | +| 出方向 | TCP | 3306 | 172.17.0.0/16 | 访问RDS | +| 出方向 | TCP | 443 | 0.0.0.0/0 | HTTPS出站 | + +**⚠️ 安全建议:** +- SSH 端口(22)建议限制为您的办公网络 IP +- 不要开放 3306 端口到公网 + +--- + +### 阶段5:部署 REDCap + +#### 5.1 验证文件结构 + +```bash +cd /opt/redcap +ls -la + +# 预期结构: +# /opt/redcap/ +# ├── Dockerfile.redcap +# ├── docker-compose.prod.yml +# ├── docker-entrypoint.sh +# ├── config/ +# │ ├── apache/redcap.conf +# │ ├── php/php.ini +# │ └── database.php +# ├── redcap15.8.0/ +# │ └── redcap/ +# └── logs/ +``` + +#### 5.2 测试数据库连接 + +```bash +# 测试 RDS 连接 +mysql -h rm-2ze9587199003517c.mysql.rds.aliyuncs.com \ + -u redcap_user -p \ + -e "SELECT 1;" +``` + +#### 5.3 构建并启动容器 + +```bash +cd /opt/redcap + +# 构建镜像 +docker-compose -f docker-compose.prod.yml build + +# 启动容器 +docker-compose -f docker-compose.prod.yml up -d + +# 查看状态 +docker-compose -f docker-compose.prod.yml ps + +# 查看日志 +docker-compose -f docker-compose.prod.yml logs -f +``` + +#### 5.4 初始化 REDCap 数据库 + +**方式1:使用安装向导(推荐)** + +1. 访问 http://39.105.153.58/install.php +2. 按照向导完成安装 +3. 创建管理员账户 + +**方式2:导入 SQL 文件** + +```bash +# 如果有现成的 redcap_install.sql +mysql -h rm-2ze9587199003517c.mysql.rds.aliyuncs.com \ + -u redcap_user -p redcap_prod < redcap_install.sql +``` + +--- + +### 阶段6:验证部署 + +#### 6.1 访问测试 + +| 测试项 | URL | 预期结果 | +|--------|-----|---------| +| 首页 | http://39.105.153.58/ | 显示REDCap登录页 | +| 安装向导 | http://39.105.153.58/install.php | 显示安装页面 | +| 控制中心 | http://39.105.153.58/ControlCenter/ | 需登录后访问 | + +#### 6.2 功能验证清单 + +- [ ] 页面样式正常,无404错误 +- [ ] 可以成功登录 +- [ ] 可以创建项目 +- [ ] 可以创建表单 +- [ ] 数据可以正常保存 +- [ ] API 可以正常调用 + +--- + +## 🔒 安全加固(重要!) + +### 7.1 修改 REDCap Base URL + +登录后在 Control Center 修改: + +``` +Configuration > General Configuration > REDCap base URL +设置为: http://39.105.153.58 +(或您的域名: https://redcap.yourdomain.com) +``` + +### 7.2 配置 HTTPS(强烈建议) + +**方式1:使用阿里云 SSL 证书** + +1. 申请免费 SSL 证书(阿里云控制台) +2. 下载证书文件 +3. 配置 Nginx 反向代理或修改 Apache 配置 + +**方式2:使用 Let's Encrypt** + +```bash +# 安装 Certbot +sudo yum install -y certbot + +# 获取证书(需要域名指向此服务器) +sudo certbot certonly --standalone -d redcap.yourdomain.com +``` + +### 7.3 定期备份 + +```bash +# 创建备份脚本 +cat > /opt/redcap/backup.sh << 'EOF' +#!/bin/bash +DATE=$(date +%Y%m%d) +BACKUP_DIR=/opt/redcap/backups + +mkdir -p $BACKUP_DIR + +# 备份数据库 +mysqldump -h rm-2ze9587199003517c.mysql.rds.aliyuncs.com \ + -u redcap_user -p'YOUR_PASSWORD' \ + redcap_prod > $BACKUP_DIR/redcap_db_$DATE.sql + +# 备份 edocs +docker cp redcap-prod:/var/www/html/redcap/edocs $BACKUP_DIR/edocs_$DATE + +# 保留最近7天 +find $BACKUP_DIR -mtime +7 -delete + +echo "Backup completed: $DATE" +EOF + +chmod +x /opt/redcap/backup.sh + +# 添加定时任务(每天凌晨2点) +echo "0 2 * * * /opt/redcap/backup.sh" | crontab - +``` + +--- + +## 📋 部署检查清单 + +### 部署前 + +- [ ] ECS 服务器已启动 +- [ ] RDS MySQL 已启动 +- [ ] RDS 白名单已添加 ECS 私网 IP +- [ ] 安全组已配置 80/443 端口 +- [ ] REDCap 源码已上传 +- [ ] database.php 已配置正确的 RDS 连接信息 +- [ ] Salt 值已设置并记录(永不可变!) + +### 部署后 + +- [ ] 容器状态正常(docker-compose ps) +- [ ] 可以访问 http://39.105.153.58/ +- [ ] 页面样式正常 +- [ ] 可以成功登录 +- [ ] 可以创建项目并保存数据 +- [ ] 备份脚本已配置 +- [ ] (可选)HTTPS 已配置 + +--- + +## 🛠️ 常用运维命令 + +```bash +# 进入部署目录 +cd /opt/redcap + +# 查看容器状态 +docker-compose -f docker-compose.prod.yml ps + +# 查看日志 +docker-compose -f docker-compose.prod.yml logs -f + +# 重启服务 +docker-compose -f docker-compose.prod.yml restart + +# 停止服务 +docker-compose -f docker-compose.prod.yml stop + +# 启动服务 +docker-compose -f docker-compose.prod.yml start + +# 重建容器(代码更新后) +docker-compose -f docker-compose.prod.yml up -d --build + +# 进入容器 +docker exec -it redcap-prod bash + +# 查看磁盘使用 +docker system df +``` + +--- + +## ⚠️ 重要注意事项 + +### Salt 值 + +``` +⚠️ Salt 值一旦设置,永远不可更改! +用于数据去标识化哈希,更改将导致所有去标识化数据失效。 +请务必记录并安全保存。 +``` + +### 密码安全 + +- 数据库密码建议 32+ 字符 +- 定期更换管理员密码 +- 不要在代码中硬编码密码 + +### 数据备份 + +- 每日自动备份数据库 +- edocs 目录包含上传文件,需备份 +- 备份文件建议同步到 OSS + +--- + +## 📚 相关文档 + +- [Docker部署操作手册](./10-REDCap_Docker部署操作手册.md) +- [部署问题排查手册](./13-部署问题排查手册.md) +- [REDCap API使用指南](../03-API对接与开发/30-REDCap_API使用指南.md) + +--- + +## 📝 更新记录 + +| 日期 | 版本 | 更新内容 | +|------|------|---------| +| 2026-02-02 | v1.0 | 初始版本,基于 ECS + RDS 架构 | + +--- + +**文档维护:** AI Clinical Research 开发团队 +**有问题?** 查看 [部署问题排查手册](./13-部署问题排查手册.md) diff --git a/docs/03-业务模块/Redcap/01-部署与配置/15-REDCap生产环境部署信息记录.md b/docs/03-业务模块/Redcap/01-部署与配置/15-REDCap生产环境部署信息记录.md new file mode 100644 index 00000000..7235e7cd --- /dev/null +++ b/docs/03-业务模块/Redcap/01-部署与配置/15-REDCap生产环境部署信息记录.md @@ -0,0 +1,321 @@ +# REDCap 生产环境部署信息记录 + +**创建日期:** 2026-02-02 +**最后更新:** 2026-02-02 +**状态:** ✅ 部署成功运行中(HTTPS + 域名已配置) +**⚠️ 机密文档:** 请妥善保管,不要提交到公开代码仓库 + +--- + +## 🌐 访问地址 + +| 服务 | 地址 | 备注 | +|------|------|------| +| **REDCap 主页** | https://redcap.xunzhengyixue.com/ | ✅ 生产环境(推荐) | +| **REDCap 控制中心** | https://redcap.xunzhengyixue.com/ControlCenter/ | 管理员入口 | +| **REDCap API** | https://redcap.xunzhengyixue.com/api/ | API 接口 | +| **备用地址(IP)** | http://39.105.153.58/ | 会重定向到 HTTPS | + +--- + +## 🖥️ ECS 服务器信息 + +| 项目 | 值 | +|------|-----| +| **实例名称** | launch-advisor-20260108 | +| **实例ID** | i-2ze51hziwjg23m2u1fg4 | +| **公网IP** | `39.105.153.58` | +| **私网IP** | `172.17.173.82` | +| **规格** | ecs.u2a-c1m2.large (2核 4GB) | +| **操作系统** | Alibaba Cloud Linux 3.2104 LTS | +| **可用区** | 华北2(北京)F | +| **到期时间** | 2027-01-09 | +| **VPC** | vpc-2ze055cptkew9c38w4r06 | + +### SSH 登录信息 + +```bash +ssh root@39.105.153.58 +``` + +| 项目 | 值 | +|------|-----| +| **用户名** | root | +| **密码** | `Xilu,881009` | + +--- + +## 🗄️ RDS MySQL 数据库信息 + +| 项目 | 值 | +|------|-----| +| **实例ID** | rm-2ze9587199003517c | +| **数据库类型** | MySQL 8.0 | +| **规格** | mysql.n2e.medium.1 (2核 4GB) | +| **内网地址** | `rm-2ze9587199003517c.mysql.rds.aliyuncs.com` | +| **端口** | 3306 | +| **可用区** | 华北2(北京)F | +| **到期时间** | 2027-01-09 | + +### REDCap 数据库 + +| 项目 | 值 | +|------|-----| +| **数据库名** | `redcap_prod` | +| **字符集** | utf8mb4 | +| **用户名** | `redcap_user` | +| **密码** | `Xilu@881009` | + +### 数据库连接命令 + +```bash +mysql -h rm-2ze9587199003517c.mysql.rds.aliyuncs.com -u redcap_user -p'Xilu@881009' redcap_prod +``` + +--- + +## 👤 REDCap 管理员账户 + +| 项目 | 值 | +|------|-----| +| **用户名** | `admin` | +| **密码** | `Xilu,881009` | +| **权限** | 超级管理员 | + +--- + +## 🔐 关键安全信息 + +### Salt 值(⚠️ 永不可变!) + +``` +redcap_prod_salt_2026_xilu_medical_v1_never_change +``` + +> **警告**:Salt 值用于数据去标识化哈希,一旦设置**永远不能更改**! +> 更改将导致所有去标识化数据失效,请务必备份保存。 + +### database.php 配置文件位置 + +``` +ECS 路径: /opt/redcap/config/database.php +容器内路径: /var/www/html/redcap/database.php +``` + +--- + +## 🐳 Docker 部署信息 + +### 文件路径 + +| 文件/目录 | 路径 | +|----------|------| +| **部署根目录** | `/opt/redcap/` | +| **REDCap 源码** | `/opt/redcap/redcap15.8.0/redcap/` | +| **Docker Compose 文件** | `/opt/redcap/docker-compose.prod.yml` | +| **Dockerfile** | `/opt/redcap/Dockerfile.redcap` | +| **database.php** | `/opt/redcap/config/database.php` | +| **Apache 配置** | `/opt/redcap/config/apache/redcap.conf` | +| **PHP 配置** | `/opt/redcap/config/php/php.ini` | +| **日志目录** | `/opt/redcap/logs/` | + +### Docker 信息 + +| 项目 | 值 | +|------|-----| +| **容器名称** | redcap-prod | +| **镜像名称** | redcap-redcap-web | +| **Docker 版本** | 26.1.3 | +| **Docker Compose 版本** | v2.27.0 | + +### Docker 数据卷 + +| 卷名 | 用途 | 备注 | +|------|------|------| +| redcap-edocs-prod | 上传文件 | **重要!需定期备份** | +| redcap-modules-prod | External Modules | 可选备份 | +| redcap-temp-prod | 临时文件 | 可定期清理 | + +### 常用 Docker 命令 + +```bash +# 进入部署目录 +cd /opt/redcap + +# 查看容器状态 +docker compose -f docker-compose.prod.yml ps + +# 查看日志 +docker logs redcap-prod --tail 100 + +# 重启服务 +docker compose -f docker-compose.prod.yml restart + +# 停止服务 +docker compose -f docker-compose.prod.yml stop + +# 启动服务 +docker compose -f docker-compose.prod.yml start + +# 进入容器 +docker exec -it redcap-prod bash +``` + +--- + +## 🔧 Docker 镜像加速器配置 + +配置文件:`/etc/docker/daemon.json` + +```json +{ + "registry-mirrors": [ + "https://docker.1panel.live", + "https://dockerpull.org", + "https://docker.rainbond.cc", + "https://docker.m.daocloud.io" + ] +} +``` + +--- + +## 🛡️ 安全组配置 + +| 规则 | 协议 | 端口 | 授权对象 | +|------|------|------|---------| +| 入方向 | ALL | 全部 | 0.0.0.0/0 | + +> **安全建议**:生产环境应限制 SSH 端口(22)只允许特定 IP 访问 + +--- + +## 🔒 HTTPS / SSL 配置 + +### 域名信息 + +| 项目 | 值 | +|------|-----| +| **域名** | `redcap.xunzhengyixue.com` | +| **DNS 解析** | A 记录 → `39.105.153.58` | +| **SSL 证书** | 阿里云免费证书(DV) | +| **证书有效期** | 1 年(需定期续期) | + +### Nginx 反向代理 + +| 项目 | 值 | +|------|-----| +| **Nginx 版本** | 系统默认 | +| **配置文件** | `/etc/nginx/conf.d/redcap.conf` | +| **SSL 证书路径** | `/etc/nginx/ssl/redcap.xunzhengyixue.com.pem` | +| **SSL 私钥路径** | `/etc/nginx/ssl/redcap.xunzhengyixue.com.key` | +| **代理目标** | `http://127.0.0.1:8080` | + +### 架构说明 + +``` +用户访问 https://redcap.xunzhengyixue.com + ↓ + Nginx (443/80) ← SSL 终止 + ↓ + Docker 容器 (8080) ← REDCap Apache + ↓ + RDS MySQL (3306) ← 数据库 +``` + +### Nginx 常用命令 + +```bash +# 检查配置 +nginx -t + +# 重启 Nginx +systemctl restart nginx + +# 查看状态 +systemctl status nginx + +# 查看日志 +tail -f /var/log/nginx/error.log +``` + +--- + +## 📦 软件版本 + +| 软件 | 版本 | +|------|------| +| REDCap | 15.8.0 | +| PHP | 8.1.x | +| Apache | 2.4.65 | +| MySQL | 8.0 (RDS) | +| Nginx | 系统默认 | +| Docker | 26.1.3 | +| Docker Compose | v2.27.0 | +| 操作系统 | Alibaba Cloud Linux 3.2104 | + +--- + +## 💾 备份策略 + +### 数据库备份命令 + +```bash +# 手动备份 +mysqldump -h rm-2ze9587199003517c.mysql.rds.aliyuncs.com \ + -u redcap_user -p'Xilu@881009' \ + redcap_prod > /opt/redcap/backups/redcap_db_$(date +%Y%m%d).sql + +# 备份 edocs(上传文件) +docker cp redcap-prod:/var/www/html/redcap/edocs /opt/redcap/backups/edocs_$(date +%Y%m%d) +``` + +### 建议备份频率 + +| 数据类型 | 频率 | 保留时间 | +|---------|------|---------| +| 数据库 | 每日 | 30 天 | +| edocs 文件 | 每周 | 90 天 | +| 配置文件 | 每次修改后 | 永久 | + +--- + +## 📋 部署时间线 + +| 日期 | 事件 | +|------|------| +| 2026-02-02 | ECS 服务器初始化,安装 Docker CE 26.1.3 | +| 2026-02-02 | 配置 Docker 镜像加速器(国内源) | +| 2026-02-02 | RDS MySQL 配置,创建数据库 redcap_prod 和用户 | +| 2026-02-02 | REDCap 15.8.0 源码和配置文件上传 | +| 2026-02-02 | Docker 容器构建和启动 | +| 2026-02-02 | 执行 redcap_install.sql 初始化数据库表 | +| 2026-02-02 | ✅ REDCap 生产环境部署完成(HTTP) | +| 2026-02-02 | 配置域名 redcap.xunzhengyixue.com DNS 解析 | +| 2026-02-02 | 申请并配置阿里云 SSL 证书 | +| 2026-02-02 | 安装 Nginx 反向代理,配置 HTTPS | +| 2026-02-02 | ✅ HTTPS + 域名配置完成 | + +--- + +## ⚠️ 重要提醒 + +1. **Salt 值永不可变** - 更改将导致数据损坏 +2. **定期备份数据库** - 防止数据丢失 +3. **定期更新密码** - 增强安全性 +4. **监控服务器状态** - 及时发现问题 +5. **不要将此文档提交到公开仓库** - 包含敏感信息 + +--- + +## 📞 技术支持 + +- REDCap 官方文档:https://projectredcap.org/ +- 部署操作手册:[10-REDCap_Docker部署操作手册.md](./10-REDCap_Docker部署操作手册.md) +- ECS 部署方案:[14-REDCap_ECS生产环境部署方案.md](./14-REDCap_ECS生产环境部署方案.md) +- 问题排查手册:[13-部署问题排查手册.md](./13-部署问题排查手册.md) + +--- + +**文档版本**:v1.0 +**创建者**:AI Clinical Research 开发团队 diff --git a/frontend-v2/src/modules/aia/styles/chat-workspace.css b/frontend-v2/src/modules/aia/styles/chat-workspace.css index 6e50bea2..0a72fc17 100644 --- a/frontend-v2/src/modules/aia/styles/chat-workspace.css +++ b/frontend-v2/src/modules/aia/styles/chat-workspace.css @@ -1035,4 +1035,3 @@ font-family: 'Monaco', 'Consolas', 'Courier New', monospace; font-size: 0.9em; } -