feat(ssa): Complete T-test end-to-end testing with 9 bug fixes - Phase 1 core 85% complete. R service: missing value auto-filter. Backend: error handling, variable matching, dynamic filename. Frontend: module activation, session isolation, error propagation. Full flow verified.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-02-19 20:57:00 +08:00
parent 8137e3cde2
commit 49b5c37cb1
86 changed files with 21207 additions and 252 deletions

View File

@@ -1,11 +1,13 @@
# AIclinicalresearch 系统当前状态与开发指南
> **文档版本:** v5.3
> **文档版本:** v5.5
> **创建日期:** 2025-11-28
> **维护者:** 开发团队
> **最后更新:** 2026-02-18
> **最后更新:** 2026-02-19
> **🎉 重大里程碑:**
> - **2026-02-18SSA MVP 开发计划 v1.3 完成!** Brain-Hand架构 + 统计护栏 + HITL + 10工具MVP准予启动开发
> - **🆕 2026-02-19SSA T 检验端到端测试通过!** 完整流程验证 + 9 个 Bug 修复 + Phase 1 核心完成 85%
> - **2026-02-19SSA Week 1 开发完成!** R Docker 镜像构建成功 + 后端/前端骨架 + 规范对齐
> - **2026-02-18SSA MVP 开发计划 v1.5 完成!** Brain-Hand架构 + 统计护栏 + HITL + 专家配置体系
> - **2026-02-18RVW V2.0 Week 3 完成!** 统计验证扩展 + 负号归一化 + 文件格式提示 + 用户体验优化
> - **2026-02-18RVW V2.0 Skills 架构完成!** Skills 核心框架 + 3个 Skill 实现 + ReviewWorker 改造
> - **2026-02-17RVW V2.0 "数据侦探" Day 6 完成!** L2统计验证器 + L2.5一致性取证SE三角验证、SD>Mean
@@ -20,14 +22,14 @@
> - **2026-01-24Protocol Agent 框架完成!** 可复用Agent框架+5阶段对话流程
> - **2026-01-22OSS 存储集成完成!** 阿里云 OSS 正式接入平台基础层
>
> **最新进展(RVW V2.0 Week 3 完成 2026-02-18**
> - ✅ **负号归一化**6 种 Unicode 负号变体支持,防止 float() 崩溃
> - ✅ **T 检验验证增强**:智能样本量提取 + subrow 精确高亮
> - ✅ **SE 三角/CI-P 验证增强**:多行单元格 subrow 支持
> - ✅ **前端翻译映射更新**6 种新 IssueType 中文翻译
> - ✅ **文件格式提示**PDF/.doc 上传时提示无法数据验证
> - ✅ **Skills 核心框架**types、registry、executor、profile、context
> - ✅ **3 个 Skill 实现**DataForensics、Editorial、Methodology
> **🆕 最新进展(SSA T 检验端到端测试通过 2026-02-19**
> - ✅ **🎉 完整流程验证**:数据上传 → 计划生成 → 分析执行 → 结果展示 → 代码下载
> - ✅ **R 服务 Bug 修复**:缺失值自动过滤,解决分组变量 3 组问题
> - ✅ **类型推断优化**0/1 数字列正确识别为分类变量
> - ✅ **错误处理增强**R 服务错误信息正确传递给前端显示
> - ✅ **文件名动态生成**`{toolName}_{dataName}_{MMDD}_{HHmm}.R`
> - ✅ **前端模块激活**:智能统计分析入口可用
> - ✅ **用户会话隔离**:不同用户数据正确隔离
>
> **部署状态:** ✅ 生产环境运行中 | 公网地址http://8.140.53.236/
> **REDCap 状态:** ✅ 生产环境运行中 | 地址https://redcap.xunzhengyixue.com/
@@ -68,7 +70,7 @@
| **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集成 | ⭐⭐⭐⭐⭐ | 🎉 **事件级质控V3.1完成设计100%代码60%** | **P0** |
| **SSA** | 智能统计分析 | Brain-Hand架构 + 统计护栏 + HITL + 10工具MVP | ⭐⭐⭐⭐⭐ | 🚀 **MVP计划v1.3完成设计100%,开发0%** - 准予启动开发 | **P1** |
| **SSA** | 智能统计分析 | Brain-Hand架构 + 统计护栏 + HITL + 10工具MVP | ⭐⭐⭐⭐⭐ | 🎉 **T检验端到端通过设计100%,开发85%** - Phase 1 核心完成 | **P1** |
| **ST** | 统计分析工具 | 100+轻量化统计工具 | ⭐⭐⭐⭐ | 📋 规划中 | P2 |
| **RVW** | 稿件审查系统 | 方法学评估 + 🆕数据侦探L1/L2/L2.5验证)+ Skills架构 + Word导出 | ⭐⭐⭐⭐ | 🚀 **V2.0 Week3完成85%** - 统计验证扩展+负号归一化+文件格式提示+用户体验优化 | P1 |
| **ADMIN** | 运营管理端 | Prompt管理、租户管理、用户管理、运营监控、系统知识库 | ⭐⭐⭐⭐⭐ | 🎉 **Phase 4.6完成88%** - Prompt知识库集成+动态注入 | **P0** |
@@ -92,6 +94,8 @@
│ • EmbeddingService (text-embedding-v4) │
│ • VectorSearchService (多查询+Rerank) │
│ • QueryRewriter (DeepSeek V3 查询理解) │
│ 🆕 R统计引擎ssa-r-statistics:1.0.1 Docker ✅ │
│ • plumber API | 统计护栏 | 预签名URL | 非特权用户 │
│ 前端Chat组件V2Ant Design X🆕 ✅ │
│ AIStreamChat | ThinkingBlock | useAIStream Hook │
└─────────────────────────────────────────────────────────┘
@@ -132,7 +136,7 @@
- PostgreSQL 15 Docker: pgvector/pgvector:pg15
- **pgvector 0.8.1** ✅ 2026-01-19 新增(向量数据库扩展,支持 RAG
- **pg_bigm 1.2** ✅ 2026-01-24 新增中日韩全文搜索10-100倍性能提升
- **13个Schema隔离**platform/aia/pkb/asl/dc/iit/ssa/st/rvw/admin/common/capability/ekb ✅ 2026-01-21新增
- **14个Schema隔离**platform/aia/pkb/asl/dc/iit/ssa/ssa_schema🆕/st/rvw/admin/common/capability/ekb
**云原生部署**
- 阿里云 SAE (Serverless 应用引擎)
@@ -151,9 +155,9 @@
---
## 🚀 当前开发状态2026-02-08
## 🚀 当前开发状态2026-02-19
### 🎉 最新进展:IIT 实时质控系统完成 + UI 优化计划制定2026-02-08
### 🎉 最新进展:SSA Week 1 开发完成 + R Docker 构建成功2026-02-19
#### ✅ 实时质控系统 + 管理端批量操作 + 质控驾驶舱设计

View File

@@ -37,6 +37,7 @@
| **文档处理** | `extraction_service/` | ✅ 🆕 | pymupdf4llm PDF→Markdown |
| **认证授权** | `common/auth/` | ✅ | JWT认证 + 权限控制 |
| **Prompt管理** | `common/prompt/` | ✅ | 动态Prompt配置 |
| **🆕R统计引擎** | `r-statistics-service/` | ✅ | Docker化R统计服务plumber |
### 前端通用能力

View File

@@ -0,0 +1,580 @@
# R 统计引擎架构与部署指南
> **版本:** v1.0
> **创建日期:** 2026-02-19
> **维护者:** SSA-Pro 开发团队
> **状态:** ✅ 生产就绪
---
## 📋 目录
1. [概述](#1-概述)
2. [架构设计](#2-架构设计)
3. [Docker 镜像构建](#3-docker-镜像构建)
4. [部署指南](#4-部署指南)
5. [API 参考](#5-api-参考)
6. [开发指南](#6-开发指南)
7. [运维指南](#7-运维指南)
8. [常见问题](#8-常见问题)
---
## 1. 概述
### 1.1 什么是 R 统计引擎
R 统计引擎是平台的**专用统计计算服务**,基于 Docker 容器化部署,提供:
- 🧮 **严谨的统计分析能力**T 检验、方差分析、回归等)
- 🛡️ **统计护栏**(正态性检验、方差齐性检验等)
- 📊 **可视化输出**Base64 编码的图表)
- 📝 **可复现代码生成**APA 格式的 R 脚本)
### 1.2 定位
```
┌─────────────────────────────────────────────────────────────┐
│ 业务模块层 │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ SSA-Pro │ │ 其他 │ │ 其他 │ │
│ │ 智能统计 │ │ 模块 │ │ 模块 │ │
│ └────┬────┘ └─────────┘ └─────────┘ │
├───────┼─────────────────────────────────────────────────────┤
│ ▼ 通用能力层 │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ R 统计引擎 (Docker) │ │
│ │ • /health 健康检查 │ │
│ │ • /api/v1/tools 工具列表 │ │
│ │ • /api/v1/skills 技能执行 │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
```
### 1.3 技术栈
| 组件 | 版本 | 说明 |
|------|------|------|
| R | 4.3.3 | 统计计算核心 |
| plumber | 1.2.1 | REST API 框架 |
| ggplot2 | 最新 | 数据可视化 |
| car | 3.1-2 | 高级统计检验 |
| dplyr/tidyr | 最新 | 数据处理 |
| Docker | 24+ | 容器化部署 |
---
## 2. 架构设计
### 2.1 Brain-Hand 模型
R 统计引擎采用 **Brain-Hand 分离架构**
```
┌──────────────────┐ ┌──────────────────┐
│ Node.js │ │ R Docker │
│ (Brain) │ │ (Hand) │
├──────────────────┤ ├──────────────────┤
│ • 业务逻辑 │ HTTP │ • 统计计算 │
│ • 认证鉴权 │ ───────> │ • 数据处理 │
│ • OSS 签名 │ │ • 图表生成 │
│ • 结果解释 │ <─────── │ • 代码生成 │
└──────────────────┘ JSON └──────────────────┘
```
### 2.2 数据传输协议
支持两种数据传输方式:
| 方式 | 条件 | 字段 |
|------|------|------|
| **inline** | 数据 < 2MB | `data_source.data` (JSON) |
| **oss** | 数据 >= 2MB | `data_source.oss_url` (预签名 URL) |
```json
// 方式 1: inline
{
"data_source": {
"type": "inline",
"data": [{"group": "A", "value": 10}, ...]
}
}
// 方式 2: oss (预签名 URL)
{
"data_source": {
"type": "oss",
"oss_url": "https://bucket.oss.com/data.csv?signature=xxx"
}
}
```
### 2.3 安全设计
| 安全措施 | 实现方式 |
|----------|----------|
| 非特权用户 | `USER appuser` |
| 路径遍历防护 | `tool_code` 正则白名单 `^[A-Z][A-Z0-9_]*$` |
| OSS 密钥隔离 | Node.js 生成预签名 URLR 无需持有密钥 |
| 健康检查 | Docker HEALTHCHECK |
---
## 3. Docker 镜像构建
### 3.1 完整 Dockerfile
```dockerfile
FROM rocker/r-ver:4.3
LABEL maintainer="dev-team@aiclinicalresearch.com"
LABEL version="1.0.1"
LABEL description="SSA-Pro R Statistics Service"
# 安装系统依赖(包括 R 包编译所需的库)
RUN apt-get update && apt-get install -y \
libcurl4-openssl-dev \
libssl-dev \
libxml2-dev \
libsodium-dev \
zlib1g-dev \
libnlopt-dev \
liblapack-dev \
libblas-dev \
gfortran \
pkg-config \
cmake \
curl \
&& rm -rf /var/lib/apt/lists/*
# 直接安装 R 包
RUN R -e "install.packages(c( \
'plumber', \
'jsonlite', \
'ggplot2', \
'glue', \
'dplyr', \
'tidyr', \
'base64enc', \
'yaml', \
'car', \
'httr' \
), repos='https://cloud.r-project.org/', Ncpus=2)"
# 安全加固:创建非特权用户
RUN useradd -m -s /bin/bash appuser
WORKDIR /app
# 复制应用代码
COPY plumber.R plumber.R
COPY utils/ utils/
COPY tools/ tools/
COPY tests/ tests/
# 设置目录权限
RUN chown -R appuser:appuser /app
# 切换到非特权用户
USER appuser
EXPOSE 8080
# 环境变量
ENV DEV_MODE="false"
# 健康检查
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD curl -f http://localhost:8080/health || exit 1
# 启动服务
CMD ["R", "-e", "plumber::plumb('plumber.R')$run(host='0.0.0.0', port=8080)"]
```
### 3.2 系统依赖说明
| 依赖包 | 用途 |
|--------|------|
| `libcurl4-openssl-dev` | httr 包HTTP 请求) |
| `libssl-dev` | openssl 包(加密) |
| `libxml2-dev` | xml2 包XML 解析) |
| `libsodium-dev` | sodium 包(加密) |
| `zlib1g-dev` | httpuv 包Web 服务器) |
| `libnlopt-dev` | nloptr 包(优化算法) |
| `liblapack-dev` | 线性代数计算 |
| `libblas-dev` | 基础线性代数 |
| `gfortran` | Fortran 编译器(部分 R 包需要) |
| `cmake` | nloptr 包构建 |
| `curl` | 健康检查 |
### 3.3 构建命令
```bash
# 本地构建
cd r-statistics-service
docker build -t ssa-r-statistics:1.0.1 .
# 查看镜像
docker images ssa-r-statistics
# 预期输出
REPOSITORY TAG IMAGE ID CREATED SIZE
ssa-r-statistics 1.0.1 xxxxxxxxxxxx x minutes ago 1.81GB
```
### 3.4 构建时间参考
| 阶段 | 耗时 |
|------|------|
| 基础镜像下载 | ~2 分钟(首次) |
| 系统依赖安装 | ~1 分钟 |
| R 包安装 | ~6 分钟 |
| **总计** | **~9 分钟** |
---
## 4. 部署指南
### 4.1 开发环境
使用 docker-compose
```yaml
# r-statistics-service/docker-compose.yml
version: '3.8'
services:
ssa-r-service:
build: .
container_name: ssa-r-statistics
ports:
- "8082:8080" # 主机8082 → 容器8080REDCap占用8080/8081
environment:
- DEV_MODE=true
volumes:
# 开发环境挂载:支持热重载
- ./tools:/app/tools
- ./utils:/app/utils
- ./tests:/app/tests
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"] # 容器内部仍是8080
interval: 30s
timeout: 10s
retries: 3
start_period: 10s
```
启动命令:
```bash
cd r-statistics-service
docker-compose up -d
```
### 4.2 生产环境 (SAE)
```yaml
# SAE 配置
容器镜像: registry.cn-beijing.aliyuncs.com/aiclinical/ssa-r-statistics:1.0.1
实例规格: 2 vCPU, 4 GB
最小实例: 1
最大实例: 5
端口: 8080
环境变量:
DEV_MODE: "false"
```
### 4.3 环境变量
| 变量 | 默认值 | 说明 |
|------|--------|------|
| `DEV_MODE` | `false` | 开发模式(启用热重载,每次请求重新加载工具脚本) |
> **说明**:开发环境和生产环境都使用真实 OSS无需 Mock 数据。
> - 开发环境:`ai-clinical-data-dev` bucket
> - 生产环境:`ai-clinical-data` bucket
### 4.4 端口配置
| 环境 | 主机端口 | 容器端口 | 说明 |
|------|----------|----------|------|
| **开发环境** | 8082 | 8080 | 避免与 REDCap 8080/8081 冲突 |
| **生产环境 (SAE)** | 8080 | 8080 | 云端无端口冲突 |
> **注意**Node.js 后端通过 `R_SERVICE_URL` 环境变量配置 R 服务地址,默认值为 `http://localhost:8082`。
---
## 5. API 参考
### 5.1 健康检查
```http
GET /health
```
**响应:**
```json
{
"status": "ok",
"timestamp": "2026-02-19 08:00:00",
"version": "1.0.1",
"dev_mode": true,
"tools_loaded": 1
}
```
### 5.2 工具列表
```http
GET /api/v1/tools
```
**响应:**
```json
{
"status": "ok",
"tools": ["t_test_ind", "anova_oneway"],
"count": 2
}
```
### 5.3 执行技能
```http
POST /api/v1/skills/{tool_code}
Content-Type: application/json
```
**请求体:**
```json
{
"data_source": {
"type": "inline",
"data": [...]
},
"params": {
"group_var": "group",
"value_var": "value"
},
"guardrails": {
"check_normality": true
}
}
```
**成功响应:**
```json
{
"status": "success",
"message": "分析完成",
"warnings": null,
"results": {
"method": "Welch Two Sample t-test",
"statistic": -5.196,
"df": 5.98,
"p_value": 0.002,
"p_value_fmt": "p = .002"
},
"plots": ["data:image/png;base64,..."],
"trace_log": [...],
"reproducible_code": "..."
}
```
**错误响应:**
```json
{
"status": "error",
"error_code": "E001",
"error_type": "business",
"message": "列名 'xxx' 在数据中不存在",
"user_hint": "请检查变量名是否拼写正确"
}
```
---
## 6. 开发指南
### 6.1 添加新工具
1.`tools/` 目录创建 R 脚本:
```r
# tools/my_analysis.R
#' @tool_code ST_MY_ANALYSIS
#' @name 我的分析工具
#' @version 1.0.0
# 统一入口函数
run_analysis <- function(input) {
# 加载数据
df <- load_input_data(input)
# 参数
p <- input$params
# 护栏检查
# ...
# 核心计算
# ...
# 返回结果
return(list(
status = "success",
message = "分析完成",
results = list(...)
))
}
```
2. 重启服务(开发模式无需重启)
3. 测试:
```bash
curl -X POST http://localhost:8082/api/v1/skills/ST_MY_ANALYSIS \
-H "Content-Type: application/json" \
-d '{"data_source": {...}, "params": {...}}'
```
### 6.2 工具命名规范
| 项目 | 规范 |
|------|------|
| 文件名 | 小写下划线:`t_test_ind.R` |
| tool_code | 大写下划线:`ST_T_TEST_IND` |
| 入口函数 | 固定名称:`run_analysis` |
### 6.3 结果格式规范
```r
return(list(
status = "success" | "error" | "blocked",
message = "...",
warnings = c("...") | NULL,
results = list(
# 统计结果
),
plots = list(
"data:image/png;base64,..."
),
trace_log = c("..."),
reproducible_code = "..."
))
```
---
## 7. 运维指南
### 7.1 日志查看
```bash
# 实时日志
docker logs -f ssa-r-statistics
# 最近 100 行
docker logs --tail 100 ssa-r-statistics
```
### 7.2 性能监控
```bash
# 容器资源使用
docker stats ssa-r-statistics
```
### 7.3 重启服务
```bash
# 开发环境
docker-compose restart
# 生产环境 (SAE)
通过 SAE 控制台重启实例
```
### 7.4 镜像更新
```bash
# 1. 构建新镜像
docker build -t ssa-r-statistics:1.0.2 .
# 2. 推送到镜像仓库
docker tag ssa-r-statistics:1.0.2 registry.cn-beijing.aliyuncs.com/aiclinical/ssa-r-statistics:1.0.2
docker push registry.cn-beijing.aliyuncs.com/aiclinical/ssa-r-statistics:1.0.2
# 3. 更新 SAE 部署
```
---
## 8. 常见问题
### Q1: 构建时 httpuv 安装失败
**错误:** `fatal error: zlib.h: No such file or directory`
**解决:** 添加 `zlib1g-dev` 到系统依赖
### Q2: 构建时 nloptr 安装失败
**错误:** `CMAKE NOT FOUND`
**解决:** 添加 `cmake` 到系统依赖
### Q3: /tmp 权限问题
**错误:** `cannot open file '/tmp/Rtmpxxx': No such file or directory`
**解决:** 不要在启动命令中清理 /tmp
### Q4: DEV_MODE 热重载不生效
**原因:** 没有挂载 volumes
**解决:**
```yaml
volumes:
- ./tools:/app/tools
```
### Q5: 容器启动后无法访问
**检查:**
1. 端口映射是否正确
2. 健康检查是否通过
3. 查看容器日志
---
## 附录:文件结构
```
r-statistics-service/
├── Dockerfile # 生产镜像定义
├── docker-compose.yml # 开发环境编排
├── renv.lock # R 包版本锁定(备用)
├── .Rprofile # R 启动配置(备用)
├── plumber.R # API 入口
├── utils/
│ ├── data_loader.R # 数据加载(预签名 URL
│ ├── guardrails.R # 统计护栏
│ ├── error_codes.R # 错误映射
│ └── result_formatter.R # 结果格式化
├── tools/
│ └── t_test_ind.R # 独立样本 T 检验
├── tests/
│ └── fixtures/
│ └── normal_data.csv # 测试数据
├── metadata/ # 工具元数据(预留)
└── templates/ # 解释模板(预留)
```
---
**文档结束**

View File

@@ -1,17 +1,33 @@
# SSA智能统计分析模块 - 当前状态与开发指南
> **文档版本:** v1.0
> **文档版本:** v1.5
> **创建日期:** 2026-02-18
> **最后更新:** 2026-02-18
> **最后更新:** 2026-02-19
> **维护者:** 开发团队
> **当前状态:** 📋 **MVP 开发计划 v1.3 完成,准予启动开发**
> **当前状态:** 🎉 **T 检验端到端测试通过MVP Phase 1 核心完成 85%**
> **文档目的:** 快速了解SSA模块状态为新AI助手提供上下文
>
> **🎉 里程碑2026-02-18**
> - ✅ **PRD 完成**SSA-Pro 严谨型智能统计分析模块需求定义
> - ✅ **架构设计 V4 完成**Brain-Hand 双层架构 + 统计护栏 + HITL 人机协同
> - ✅ **MVP 开发计划 v1.3 完成**:通过 3团队评审,准予启动开发
> - ✅ **MVP 开发计划 v1.5 完成**:通过 5 轮评审,纳入完整专家配置体系
> - ✅ **5 份开发文档完成**总览、任务清单、R服务指南、后端指南、前端指南
>
> **🎉 T 检验端到端测试通过2026-02-19**
> - ✅ **🎉 完整流程验证**:数据上传 → 计划生成 → 分析执行 → 结果展示 → 代码下载
> - ✅ **R 服务 Bug 修复**:缺失值自动过滤,解决分组变量 3 组问题
> - ✅ **类型推断优化**0/1 数字列正确识别为分类变量
> - ✅ **错误处理增强**R 服务错误信息正确传递给前端
> - ✅ **文件名动态生成**`{toolName}_{dataName}_{MMDD}_{HHmm}.R`
> - ✅ **前端模块激活**:智能统计分析入口可用
> - ✅ **用户会话隔离**:不同用户数据正确隔离
>
> **🆕 v1.5 新增特性(专家配置体系):**
> - 🆕 **统计决策表**(Goal, Y, X, Design) 四维匹配精准选工具,替代简单 RAG
> - 🆕 **R 代码库**:支持上传 100+ 成熟 R 脚本,统一 `run_analysis()` 入口
> - 🆕 **参数映射配置**JSON Key → R 参数名可配置
> - 🆕 **护栏规则链**:支持 Block / Warn / Switch 三种 Action
> - 🆕 **结果解读模板**"填空题"式的论文级结论生成
---
@@ -26,7 +42,7 @@
| **商业价值** | ⭐⭐⭐⭐⭐ 极高 |
| **独立性** | ⭐⭐⭐⭐ 高(可独立使用,也可与其他模块协同) |
| **目标用户** | 临床研究人员、生物统计师 |
| **开发状态** | 📋 **MVP 开发计划完成,准备启动开发** |
| **开发状态** | 🚀 **MVP Phase 1 开发中Week 1 完成 ~80%** |
### 核心目标
@@ -42,8 +58,9 @@
#### 核心AI能力规划中
1. **智能规划Planner**
- RAG 工具检索:根据用户意图召回最适合的统计方法
- 参数映射:将自然语言映射为统计参数
- 🆕 **决策表匹配**(Goal, Y, X, Design) 四维精准选工具
- RAG 工具检索:作为决策表的兜底方案
- 参数映射:将自然语言映射为统计参数(可配置)
- 统计分析计划SAP生成
2. **统计护栏Guardrails**
@@ -51,6 +68,7 @@
- 方差齐性检验Levene
- 样本量检验
- 大样本优化N > 5000 抽样检验)
- 🆕 **护栏 Action**Block阻止 / Warn警告 / Switch切换方法
3. **人机协同HITL**
- Plan Card用户确认/修改分析计划
@@ -62,6 +80,19 @@
- 自动注入依赖安装脚本
- APA 格式化输出p_value_fmt
5. **🆕 咨询模式**
- 无数据对话:用户只描述研究设计
- SAP 文档生成:结构化统计分析计划
- 多格式导出Word/Markdown
6. **🆕 配置中台(专家知识库)**
- 🆕 **统计决策表**Goal + Y + X + Design → Tool 映射
- 🆕 **R 代码库**100+ 成熟脚本上传,统一 `run_analysis()` 入口
- 🆕 **参数映射**JSON Key → R 参数名 + 校验规则
- 🆕 **护栏规则链**Check → Threshold → Action (Block/Warn/Switch)
- 🆕 **结果解读模板**"填空题"式论文级结论
- Excel 配置导入 + 热加载 + 配置校验
#### MVP 工具清单10个
| 工具代码 | 工具名称 | 适用场景 |
@@ -81,28 +112,30 @@
## 🏗️ 架构设计
### Brain-Hand 双层架构
### Brain-Hand 双层架构 + 配置中台
```
┌─────────────────────────────────────────────────────────┐
│ 用户界面 (Frontend) │
│ DataUploader | PlanCard | ExecutionTrace | ResultCard │
🆕 ModeSwitch | DataUploader | PlanCard | ResultCard │
│ ↓ 智能分析 ↓ 咨询模式 │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
Brain Layer (Node.js)
Planner (Brain/大脑) - Node.js │
│ ┌─────────────────────────────────────────────────────┐│
│ │ DataParserService: 数据解析 → Schema 提取 ││
│ │ ToolRetrievalService: RAG 工具检索 ││
│ │ PlannerService: LLM 规划 + 参数映射 ││
│ │ RClientService: R 服务调用(混合数据协议) ││
│ │ PlannerService: LLM 规划(有数据) ││
│ │ 🆕 ConsultService: 无数据咨询 ││
│ │ 🆕 SAPGeneratorService: SAP 文档生成 ││
│ │ CriticService: 结果解读(流式) ││
│ └─────────────────────────────────────────────────────┘│
│ 📌 只看 Schema(无真实数据)
│ 📌 只看 Schema,支持有数据/无数据两种模式
└─────────────────────────────────────────────────────────┘
(仅智能分析模式)
┌─────────────────────────────────────────────────────────┐
Hand Layer (R Docker)
Executor (Hand/四肢) - R Docker │
│ ┌─────────────────────────────────────────────────────┐│
│ │ data_loader.R: 混合数据协议inline/OSS ││
│ │ guardrails.R: 统计护栏(正态/方差齐性/样本量) ││
@@ -111,6 +144,16 @@
│ │ error_codes.R: 结构化错误码 ││
│ └─────────────────────────────────────────────────────┘│
│ 📌 操作真实数据 + 生成可复现代码 │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ 🆕 配置中台 (Config Center) │
│ ┌─────────────────────────────────────────────────────┐│
│ │ ConfigLoaderService: Excel 配置加载 ││
│ │ ConfigValidatorService: 配置校验 ││
│ │ ConfigCacheService: 配置缓存 + 热加载 ││
│ └─────────────────────────────────────────────────────┘│
│ 📌 统计专家可配置,系统动态加载 │
└─────────────────────────────────────────────────────────┘
```
@@ -128,14 +171,23 @@
## 📋 开发进度
| Phase | 任务 | 状态 | 计划日期 |
| Phase | 任务 | 状态 | 完成日期 |
|-------|------|------|---------|
| Phase 0 | 需求分析与架构设计 | ✅ 已完成 | 2026-02-18 |
| Phase 0 | MVP 开发计划 v1.0 → v1.3 | ✅ 已完成 | 2026-02-18 |
| Phase 1 | 骨架搭建T检验端到端 | 📋 待开始 | - |
| Phase 2 | 智能与交互RAG + HITL | 📋 待开始 | - |
| Phase 3 | 打磨与调试 | 📋 待开始 | - |
| **总计** | - | **设计 100%,开发 0%** | - |
| Phase 0 | MVP 开发计划 v1.0 → v1.6 | ✅ 已完成 | 2026-02-19 |
| Phase 1 | 骨架搭建 + 配置中台 | 🎉 **核心完成 85%** | 2026-02-19 |
| Phase 2 | 智能规划 + 咨询模式 | 📋 待开始 | - |
| Phase 3 | 完善与联调 | 📋 待开始 | - |
| **总计** | 106 个任务 | **完成 38 项36%** | - |
### 🎉 Phase 1 已完成核心功能
| 组件 | 完成项 | 状态 |
|------|--------|------|
| **R 服务** | T 检验、错误码、护栏、预签名 URL、缺失值处理 | ✅ 100% |
| **后端** | 路由、RClientService、DataParserService、代码下载 | ✅ 83% |
| **前端** | 页面框架、数据上传、结果展示、代码下载、模块注册 | ✅ 100% |
| **配置中台** | 数据库表、热加载 API | 🔄 18% |
### 开发计划文档
@@ -154,6 +206,7 @@
| v1.0 | `06-开发记录/SSA-Pro 方案深度审查与风险评估报告.md` | 需修订 | 2026-02-18 |
| v1.1 | `06-开发记录/SSA-Pro 方案深度审查与风险评估报告 V2.0.md` | 需修订 | 2026-02-18 |
| v1.2 | `06-开发记录/SSA-Pro V1.2 终极审查与发令报告V3.0.md` | 🟢 通过 | 2026-02-18 |
| v1.4 | 🆕 纳入双引擎 + 咨询模式 + 配置中台 | 🟢 通过 | 2026-02-18 |
---
@@ -250,6 +303,8 @@ docs/03-业务模块/SSA-智能统计分析/
### API 接口预览
#### 智能分析模式
```http
### 创建会话
POST http://localhost:3001/api/v1/ssa/sessions
@@ -270,6 +325,39 @@ Content-Type: application/json
GET http://localhost:3001/api/v1/ssa/sessions/{sessionId}/result
```
#### 🆕 咨询模式
```http
### 创建咨询会话(无数据)
POST http://localhost:3001/api/v1/ssa/consult
### 咨询对话
POST http://localhost:3001/api/v1/ssa/consult/{sessionId}/chat
Content-Type: application/json
{"message": "我有一个双臂 RCT 研究,想比较主要终点..."}
### 生成 SAP 文档
POST http://localhost:3001/api/v1/ssa/consult/{sessionId}/generate-sap
### 下载 SAP
GET http://localhost:3001/api/v1/ssa/consult/{sessionId}/download-sap?format=word
```
#### 🆕 配置中台
```http
### 导入 Excel 配置
POST http://localhost:3001/api/v1/ssa/config/import
Content-Type: multipart/form-data
# file: config.xlsx
### 热加载配置
POST http://localhost:3001/api/v1/ssa/config/reload
### 获取工具列表
GET http://localhost:3001/api/v1/ssa/config/tools
```
---
## ⚠️ 注意事项
@@ -277,10 +365,13 @@ GET http://localhost:3001/api/v1/ssa/sessions/{sessionId}/result
### 对新AI助手
1.**设计文档已完成**开发前请先阅读架构设计V4
2.**开发计划v1.3已审批**遵循5份开发文档进行开发
3. ⚠️ **Brain-Hand 隔离**Node.js 只看 SchemaR 操作真实数据
4. ⚠️ **混合数据协议**< 2MB inline2-20MB OSS
5. ⚠️ **代码模板同步**:修改 Wrapper 逻辑时必须同步更新 templates/
2.**开发计划v1.4已审批**遵循5份开发文档进行开发
3. ⚠️ **Planner/Executor 分离**:代码目录按 planner/executor 组织
4. ⚠️ **Brain-Hand 隔离**Node.js 只看 SchemaR 操作真实数据
5. ⚠️ **支持无数据模式**:咨询模式下 Planner 可独立工作
6. ⚠️ **配置外置**:工具定义从 Excel 加载,不硬编码
7. ⚠️ **混合数据协议**< 2MB inline2-20MB OSS
8. ⚠️ **代码模板同步**:修改 Wrapper 逻辑时必须同步更新 templates/
### 风险与应对
@@ -300,7 +391,7 @@ GET http://localhost:3001/api/v1/ssa/sessions/{sessionId}/result
### MVP 阶段(当前)
- [ ] Phase 1骨架搭建T检验端到端跑通
- [x] Phase 1骨架搭建T检验端到端跑通✅ 2026-02-19
- [ ] Phase 2智能与交互RAG + HITL + 10工具
- [ ] Phase 3打磨与调试性能优化 + Bug修复
@@ -313,7 +404,7 @@ GET http://localhost:3001/api/v1/ssa/sessions/{sessionId}/result
---
**文档版本:** v1.0
**最后更新:** 2026-02-18
**当前状态:** 📋 MVP 开发计划 v1.3 完成,准予启动开发
**下一步:** Phase 1 骨架搭建
**文档版本:** v1.5
**最后更新:** 2026-02-19
**当前状态:** 🎉 T 检验端到端测试通过Phase 1 核心完成 85%
**下一步:** Phase 2 智能规划 + 更多统计方法(或完善配置中台)

View File

@@ -0,0 +1,128 @@
# **专家视角:统计分析计划 (SAP) 的解构与配置映射**
**文档版本:** v1.0
**创建日期:** 2026-02-18
**核心议题:** 从医学统计专家的视角,重新定义 Planner 的规划逻辑与 Admin 的配置要素。
## **1\. 统计专家的“问诊”逻辑 (The Statistician's Mindset)**
当医生拿着数据来找我(统计专家)时,我脑子里的思维路径是这样的:
### **第一步:明确研究目的 (Objective)**
* **专家会问**:你是要描述现状?比较差异?探索关联?还是预测未来?
* **系统映射****意图识别配置**。
* *Config*: 关键词映射表("影响因素" \-\> 回归分析;"疗效对比" \-\> 差异检验)。
### **第二步:明确数据特征 (Data Characteristics)**
* **专家会问**你的结局变量Y是什么类型的连续/分类/生存时间你的分组变量X是几组数据是独立采样的还是同一个病人前后的对比配对
* **系统映射****变量角色定义**。
* *Config*: 工具的适用数据类型约束ST\_T\_TEST\_IND 要求 Y=Numeric, X=Categorical(2 levels), Design=Independent
### **第三步:制定分析策略 (Strategy)**
* **专家会想**:既然是比较两组连续变量,先看正态性。如果正态,用 T 检验;如果不正态,用 Wilcoxon。最后还要画个图直观展示。
* **系统映射****决策树与组合配置**。
* *Config*: 不仅仅配置“一个工具”,而是配置 **"标准分析流 (SOP)"**。
## **2\. 一份标准的 SAP 包括什么? (Anatomy of SAP)**
Planner 生成的不仅仅是一个 Tool Code而应该是一份完整的**作战地图**。
### **2.1 SAP 的核心要素**
1. **分析集定义 (Analysis Set)**:全分析集 (FAS) 还是符合方案集 (PPS)MVP 阶段默认全数据)。
2. **变量操作 (Data Manipulation)**:需要计算 BMI 吗?需要把年龄分段吗?
3. **描述性统计 (Descriptive)**:基线表怎么做?(连续变量算 Mean±SD分类变量算 N(%))。
4. **推断性统计 (Inference)**:核心假设检验方法(方法论 \+ 假设前提)。
5. **图表规划 (Visualization)**:用什么图展示结果最直观?
### **2.2 我们的 Planner 应该输出什么?**
用户看到的“预习卡片”,本质上就是 SAP 的摘要版:
**🎯 统计分析计划**
1. **研究假设**:男性与女性的血糖水平存在差异。
2. **数据清洗**:剔除 GLU 为空的样本;自动计算 BMI \= Weight/Height^2。
3. **统计方法**
* 优先使用 **独立样本 T 检验**
* **前置条件**需满足正态性Shapiro-Wilk P \> 0.05)。
* **替代方案**:若不满足,转为 **Mann-Whitney U 检验**
4. **图表展示**:分组箱线图 (Boxplot) 叠加散点。
## **3\. 这种视角下,后台需要配置什么? (Config Requirements)**
我们要配置的不是“API 参数”,而是\*\*“统计学家的知识图谱”\*\*。我们需要在 Excel 中增加这几列:
### **3.1 决策逻辑配置 (Decision Logic)**
这是 Planner 的核心。专家需要定义:
| 配置项 | 含义 | 示例 (T检验) |
| :---- | :---- | :---- |
| **Goal\_Type** | 分析目的 | Difference (差异比较) |
| **Y\_Type** | 因变量类型 | Continuous (连续数值) |
| **X\_Type** | 自变量类型 | Categorical\_2 (二分类) |
| **Design\_Type** | 设计类型 | Independent (独立) |
| **Pre\_Conditions** | 前置假设 | Normality, Homogeneity |
**Planner 的逻辑**
用户输入 \-\> 提取 (Goal, X, Y) \-\> **查配置表匹配** \-\> 命中 ST\_T\_TEST\_IND。
### **3.2 完整分析流配置 (Analysis Flow)**
一个工具往往伴随着一套动作。专家需要定义“套餐”:
| 配置项 | 含义 | 示例 |
| :---- | :---- | :---- |
| **Main\_Method** | 主方法 | t.test |
| **Desc\_Method** | 描述方法 | mean\_sd (均值标准差) |
| **Plot\_Type** | 推荐图表 | boxplot \+ jitter |
| **Alt\_Method** | 替代方法 | wilcox.test (非参数) |
### **3.3 结果解读模板 (Narrative Template)**
专家要教 AI 怎么写论文里的“结果”部分。
* **配置内容**
"本研究共纳入 {{n}} 例样本。{{group\_col}} 各组间 {{val\_col}} 的差异 {{significance}} (t={{statistic}}, P={{p\_value}})。如图 1 所示,{{high\_group}} 的数值显著高于 {{low\_group}}。"
## **4\. 对架构的深层影响**
您的质疑直接推动了 **Config Center (配置中台)** 的升维。
1. **Planner 变重了**:它不能只做简单的 RAG 检索。它需要内置一个**轻量级的推理机**(基于专家配置的决策表),来模拟专家“看病”的过程。
2. **Executor 变纯粹了**:它只需要忠实地执行 SAP 中的指令(包括主方法、替代方法、画图)。
3. **Excel 配置表变复杂了**:我们需要设计一个更结构化的 Excel让专家能把这些逻辑填进去。
### **新版 Excel 配置结构预览**
**Sheet: Knowledge\_Graph (知识图谱)**
* Scenario\_ID: 场景代码 (如 DIFF\_NUM\_2GRP\_IND)
* User\_Intent: 用户意图 (差异比较)
* Data\_Pattern: 数据特征 (Y=数值, X=2分类, 独立)
* Rec\_Tool\_Code: 推荐工具 (ST\_T\_TEST\_IND)
**Sheet: Tool\_Definition (工具定义)**
* Tool\_Code: ST\_T\_TEST\_IND
* Workflow: \[Check\_Normality, Check\_Variance, Run\_Test, Plot\_Box\] (定义一连串动作)
* Report\_Template: 结果解释模板...
## **5\. 总结**
您是对的。**统计分析规划Planner的核心不是“检索”而是“匹配”和“决策”。**
我们需要了解用户的:
1. **目的** (差异/相关/预测)
2. **变量类型** (数值/分类/等级)
3. **实验设计** (独立/配对/随访)
**我们的系统配置,必须围绕这三个维度展开。** 只有这样SSA-Pro 才能生成一份让医生信服的 SAP而不仅仅是扔给用户一个 T 检验代码。

View File

@@ -0,0 +1,120 @@
# **SSA-Executor 专家配置要素清单 (Configuration Specs)**
**文档版本:** v1.0
**创建日期:** 2026-02-18
**核心目标:** 定义统计专家需要在“配置中心”为每个 R 工具录入的详细信息。
**隐喻:** 如果 R 代码是“药方”,这个配置单就是“药品说明书”。
## **1\. 基础元数据 (Identity)**
*给这个 R 脚本一个系统内唯一的身份。*
| 配置项 | 说明 | 示例 |
| :---- | :---- | :---- |
| **Tool Code** | 唯一标识符 (Primary Key) | ST\_T\_TEST\_IND |
| **Tool Name** | 显示名称 | 独立样本 T 检验 |
| **Version** | 版本号 | v1.0.2 (用于回滚) |
| **R Script File** | **上传文件** | t\_test\_ind.R (专家直接上传脚本) |
| **Entry Function** | 入口函数名 | run\_analysis |
## **2\. 输入参数映射 (Input Contract)**
*告诉 Executor这个 R 脚本需要什么原料?*
| 参数名 (JSON Key) | R 函数参数名 | 数据类型 | 校验规则 (Validator) | 默认值 |
| :---- | :---- | :---- | :---- | :---- |
| group\_col | group\_var | String | Must be column name | \- |
| val\_col | value\_var | String | Must be numeric column | \- |
| conf\_level | conf\_level | Float | 0.90 \- 0.99 | 0.95 |
| alternative | alt | String | "two.sided", "less", "greater" | "two.sided" |
## **3\. 统计护栏配置 (Guardrails Config) ⭐ 核心**
*告诉 Executor在跑核心代码前先做什么体检*
**配置模式:** 规则链 (Rule Chain)
1. **检查项 (Check)**: Shapiro-Wilk Normality Test
* **目标变量**: val\_col (按 group\_col 分组)
* **阈值 (Threshold)**: P \< 0.05
* **失败动作 (Action)**:
* \[ \] **Block**: 报错并终止 ("数据不正态,无法计算")
* \[ \] **Warn**: 继续执行,但在结果中标记警告
* \[x\] **Switch**: 自动切换到工具 ST\_WILCOXON (非参数检验)
2. **检查项 (Check)**: Sample Size
* **规则**: Min(N) \< 3
* **失败动作**: **Block** ("样本量太少,无法计算")
## **4\. 输出结果定义 (Output Definition)**
*告诉 Executor跑完代码后要给用户看什么*
### **4.1 结构化数据 (Table)**
定义返回的三线表里包含哪些指标。
* **指标 1**: Statistic (t值 / F值)
* **指标 2**: P-Value (保留 3 位小数,\<0.001 显示为 "\<0.001")
* **指标 3**: Mean ± SD (描述性统计)
* **指标 4**: CI (95%) (置信区间)
### **4.2 图表配置 (Visualization)**
定义 R 脚本生成的图表规范ggplot2 模板)。
* **图表类型**: Boxplot with Jitter (箱线图+散点)
* **X 轴映射**: group\_col
* **Y 轴映射**: val\_col
* **配色方案**: Nature / Lancet (期刊风格)
* **其它元素**: 是否标注 P 值?(Yes/No)
### **4.3 智能解读模板 (Narrative Template)**
这是给 AI (Critic) 参考的“填空题”,或者是 R 直接生成的结论。
* **模板**:"本研究纳入 {{N}} 例样本。{{group\_col}} 各组间 {{val\_col}} 的差异 **{{significance\_text}}** (t={{statistic}}, P={{p\_value}})。具体而言,{{high\_group}} 的均值 ({{mean\_1}}) 显著高于 {{low\_group}} ({{mean\_2}})。"
## **5\. 代码交付配置 (Code Handover)**
*告诉 Executor用户点击“下载代码”时给他什么*
这是一个 **glue 字符串模板**,用于生成可复现的 R 代码。
\# 模板示例
library(ggplot2)
library(stats)
\# 1\. 读取数据
data \<- read.csv("your\_data.csv")
\# 2\. 统计检验
res \<- t.test({{val\_col}} \~ {{group\_col}}, data=data, var.equal={{var\_equal}})
print(res)
\# 3\. 绘图
ggplot(data, aes(x={{group\_col}}, y={{val\_col}})) \+
geom\_boxplot(fill="\#3C5488") \+
theme\_bw() \+
labs(title="Difference Analysis")
## **6\. 环境依赖 (Dependencies)**
*告诉 Executor运行这个脚本需要装什么包*
* **Packages**: ggplot2, dplyr, car, ggpubr
* **System Libs**: libcairo2 (如果涉及特殊绘图)
## **7\. 总结:专家的工作流**
统计学专家在“配置中心”要做的事情就是:
1. **上传** 写好的 t\_test.R。
2. **勾选** 这个脚本需要的输入参数(列名)。
3. **设置** 护栏P \< 0.05 切换 Wilcoxon
4. **粘贴** 代码模板(供用户下载)。
5. **预览** 这一套配置是否能跑通测试数据。
**这才是真正的“专家协同”。**

View File

@@ -0,0 +1,228 @@
# **PRD: SSA-Pro 智能统计分析 (v2.0 双引擎架构版)**
**文档状态:** v2.1 (Optimized for User Scenarios)
**发布日期:** 2026-02-18
**文档密级:** 内部绝密
**核心变更:** \> 1\. 重构业务流程,确立“智能分析(混合模式)”为主流程。
2\. 明确“执行模式”为“标准化复用”场景,而非手动填参。
3\. 强化“专家配置”在架构中的核心地位。
## **1\. 核心变革说明 (Executive Summary)**
**致研发团队:为什么要进行这次架构升级?**
经过前几轮的技术验证与业务推演,我们发现原有的“上传-\>规划-\>执行”一条龙模式存在两个致命的业务死角:
1. **用户意图模糊**:用户往往不知道自己要做什么(如“帮我分析一下”),直接跑代码会报错或产生无意义结果。
2. **统计专家缺位**:护栏规则硬编码在代码里,统计专家无法维护,导致系统缺乏“灵魂”。
因此,我们将架构解耦为**两个独立子系统**,通过编排满足不同场景:
* **Planner大脑**:负责陪聊、澄清意图、生成方案。**(独立上线,无需数据)**
* **Executor四肢**:负责接收明确指令、跑数、出结果。**(复用之前的 R 开发成果)**
**架构拆分与用户体验的关系:**
架构上的拆分Planner/Executor是为了技术上的解耦和复用但在用户体验端对于最常见的“智能分析”场景我们将这两者**无缝串联**,给用户提供“一站式”体验。
## **2\. 研发背景与业务价值**
### **2.1 用户真实痛点**
* **场景 A (无数据)**:医生在写基金本子,还没收病人,但他急需一份《统计学分析计划书》来填表。原方案不支持此场景。
* **场景 B (数据脏)**:医生上传的 Excel 列名全是中文,且有特殊字符。原方案直接跑 R 会崩溃。
* **场景 C (隐私顾虑)**:医生不敢把数据上传到云端,但又想知道该用什么统计方法。
### **2.2 产品解决方案:双引擎 \+ 配置中台**
1. **独立咨询 (SSA-Planner)**:无需上传数据,通过多轮对话澄清意图,输出专业的 SAP (分析计划)。
2. **独立计算 (SSA-Executor)**:用户确认方案后,再上传数据,一键执行计算,交付代码。
3. **专家协同 (Config Center)**:统计专家通过 Excel 配置规则,系统动态加载,不再硬编码。
### **2.3 商业价值**
* **降低门槛**:用户不用传数据就能体验 AI 能力Planner极大地提高了转化率。
* **数据安全**:实现了逻辑(云端)与数据(本地/隔离)的彻底解耦。
## **3\. 系统架构与模块定义**
### **3.1 总体架构图**
graph TD
subgraph "用户触点"
Chat\[前端 Chat 界面\]
end
subgraph "Module A: 智能规划师 (SSA-Planner)"
Intent\[意图识别引擎\]
Clarify\[澄清引导模块\]
GenSAP\[SAP 生成模块\]
end
subgraph "Module B: 智能执行器 (SSA-Executor)"
API\[Executor API\]
R\_Core\[R Docker 容器\]
Guard\[统计护栏\]
end
subgraph "Module C: 统计配置中台 (Admin)"
Meta\[元数据管理\]
Rules\[规则引擎\]
Templates\[代码模板\]
end
Chat \--"1. 咨询/方案"--\> Intent
Intent \<--\> Clarify
Intent \--\> GenSAP
Chat \--"2. 执行/计算"--\> API
API \--\> R\_Core
Meta \-.-\> Intent
Rules \-.-\> Guard
### **3.2 模块功能详述**
#### **🧩 模块 ASSA-Planner (智能规划师)**
* **定位**:纯 NLP 应用,不涉及 R 计算。
* **输入**:自然语言 \+ (可选) 数据 Schema。
* **核心能力**
* **意图澄清**:当用户指令模糊时,主动反问("您是想做差异分析还是相关性分析?")。
* **方案生成**:检索 RAG 库,生成结构化的 JSON 计划和 Markdown 报告。
* **交付物**:《统计分析计划书》 (PDF/Word)。
#### **🧩 模块 BSSA-Executor (智能执行器)**
* **定位**:纯计算服务,无状态 API。
* **输入**skill\_code \+ params \+ data\_source。
* **核心能力**
* **混合数据加载**:支持 JSON 和 OSS 数据源。
* **护栏检查**:执行正态性、方差齐性检查。
* **结果交付**生成三线表、高清图、R 源码。
* **技术备注****这部分完全复用原 V1.3 计划中的 R 服务开发内容。**
* **注意**Executor 无法直接处理用户的自然语言。必须经由 Planner 将自然语言转化为结构化参数后,才能被调用。
#### **🧩 模块 C统计配置中台 (Config Center)**
* **定位**:专家知识注入入口。
* **MVP 实现****Excel 导入工具**。
* **配置内容**
* 工具定义Name, Desc, Usage
* 护栏阈值P \< 0.05)。
* R 代码模板Glue Template
## **4\. 核心业务流程 (User Journey)**
### **流程一:智能分析模式 (Intelligent Analysis Mode) \- ⭐ 最常见场景**
**场景**:用户有数据,有模糊的意图(如“帮我对比一下差异”),希望一站式出结果。
**架构逻辑**:串联调用 Planner \-\> Executor。
1. **用户**:上传 data.csv 并输入:“帮我对比一下吸烟组和非吸烟组的体重差异”。
2. **Planner**(后台隐形介入):
* 读取 Data Schema识别出 Group 和 Weight 列。
* 理解用户意图("对比差异"),结合变量类型(二分类 vs 连续),推荐“独立样本 T 检验”。
* 生成 Executor 能听懂的 JSON 参数。
3. **交互**:系统弹出 **\[ 方案确认卡片 \]**(由 Planner 生成)。
* *设计意图*:给用户一种“专家先审视,再执行”的安全感。
4. **用户**:点击 **\[ 确认并执行 \]**。
5. **Executor**:接收 Planner 的 JSON \-\> 跑 R 代码 \-\> 返回结果。
6. **用户**:获得结果。
### **流程二:纯咨询模式 (Consultation Mode) \- 科研设计场景**
**场景**:用户还没收集数据(无数据),在写开题报告或基金标书,需要设计统计方案。
**架构逻辑**:仅调用 Planner。
1. **用户**:“我想研究阿司匹林对心血管事件的影响,该怎么设计统计?”
2. **Planner**:检索知识库,生成《统计分析计划书 (SAP)》。
* 包含研究假设、变量定义、推荐方法Cox 回归)、样本量估算建议。
3. **用户**:下载 SAP 文档。**(流程结束)**
### **流程三:标准化复用模式 (Standardized Reuse Mode) \- 专家/高阶场景**
**场景**
1. **复用**:上周生成了一个完美的 SAP这周新数据来了直接套用不想再跟 AI 废话。
2. **专家下发**:科室主任定义好了标准分析流程,存为模板,研究生直接上传数据运行。
**架构逻辑**:跳过 Planner 推理,直接调用 Executor。
1. **用户**:上传 new\_data.csv并从“我的方案库”中选择“肺癌生存分析标准模板”或加载之前的 SAP ID
2. **系统**自动校验新数据是否符合模板要求的列名Schema Check
3. **Executor**:直接读取模板参数 \-\> 跑数 \-\> 出结果。
4. **用户**:下载结果。
## **5\. 接口与数据协议 (Schema)**
### **5.1 Planner 输出协议 (Plan JSON)**
这是连接 Planner 和 Executor 的契约。
{
"analysis\_id": "uuid",
"tool\_code": "ST\_T\_TEST\_IND",
"reasoning": "因变量为连续数值,自变量为二分类...",
"params": {
"group\_col": "Gender",
"val\_col": "BMI",
"conf\_level": 0.95
},
"guardrails": {
"check\_normality": true,
"action\_on\_fail": "switch\_to\_wilcoxon"
}
}
## **6\. 实施路线图 (Updated Roadmap)**
基于新架构,我们将开发顺序调整为 **“Planner 先行Executor 并行”**。
### **Phase 1: 智能规划师上线 (Week 1-2)**
* **目标**:上线“统计咨询 Chatbot”。
* **后端**:开发 Excel 配置导入脚本;开发 Planner Service (DeepSeek)。
* **前端**:开发咨询模式 UI。
* **专家**:整理 Top 10 工具的 Excel 配置。
* *注:此阶段不需要 R 服务参与。*
### **Phase 2: 执行器与联调 (Week 3-4)**
* **目标**:打通计算闭环。
* **R 团队**:完成 Docker 封装、数据加载器 (Data Loader)、T 检验 Wrapper。
* **后端**:对接 R API透传 Planner 的参数。
* **前端**:开发结果展示卡片。
### **Phase 3: 量产与优化 (Week 5+)**
* **目标**:覆盖更多工具。
* **R 团队**:批量复制开发剩余 9 个工具。
* **专家**:持续优化配置 Excel。
## **7\. 风险与应对**
| **风险点** | **影响** | **应对策略** |
| **Planner 瞎指挥** | 生成的参数 Executor 无法执行 | 引入 **Zod Schema 强校验**,参数不合法直接让 AI 重试。 |
| **数据列名不匹配** | R 代码报错 "Column not found" | 在 Executor 入口增加 **模糊匹配/同义词映射** 逻辑。 |
| **专家配置进度慢** | 阻塞 Planner 上线 | 提供标准模板,先配 1 个工具T检验跑通全流程。 |
## **8\. 结语**
这次架构调整不是推翻过去,而是**升维**。
我们保留了最核心的 **R 计算引擎 (Executor)**,它是我们的硬实力;
我们剥离出了 **AI 规划师 (Planner)**,它是我们的软实力;
我们引入了 **配置中台**,它是我们的护城河。
请大家基于此文档,放心开工。

View File

@@ -0,0 +1,57 @@
# **SSA-Pro 架构一致性与调整分析报告**
**分析对象:** PRD V2.0 "智能分析模式" vs. V1.3 开发计划套件 (5文档)
**分析结论:** **核心逻辑完全一致,无需重构,仅需解耦接口。**
## **1\. 核心结论:我们绕弯路了吗?**
**没有。我们只是把“隐性”的逻辑“显性化”了。**
* **V1.3 计划(原计划)**:设计了一个“串联”系统。
* 逻辑:用户上传 \-\> 系统规划(Planner) \-\> 系统执行(Executor) \-\> 结果
* **现状**:这正是 PRD V2.0 中的 **“流程一:智能分析模式”**。这是用户 90% 的使用场景。
* **V2.0 架构(新概念)**:提出了“双引擎”概念。
* 逻辑:把上述串联系统中的 规划 和 执行 两个步骤,定义为两个可以**独立调用**的模块。
**结论:**
**V1.3 的开发计划代码、Docker、数据库依然是 100% 可用的基础。** 我们不需要推翻它,只需要在写代码时,注意把 Planner 和 Executor 的代码写在不同的 Service 文件里,不要写死在一个大函数里即可。
## **2\. 详细对比与复用策略**
我们来看之前的 5 个文档,看看哪些可以直接用,哪些需要微调。
| 原文档 | V1.3 内容 | V2.0 架构要求 | 调整建议 |
| :---- | :---- | :---- | :---- |
| **02-R服务开发指南** | 定义了 R Docker、Wrapper、护栏、混合数据协议。 | 需要一个独立的计算引擎。 | **无需调整 (0%)**。 R 服务本身就是 Executor它生来就是被调用的不关心是谁调用的。 |
| **03-后端开发指南** | 定义了 RClientService (执行) 和 PlannerService (规划)。 | 需要 Planner 和 Executor 解耦。 | **微调接口 (10%)**。 原计划中可能有一个 runAnalysis() 函数把两步连起来写了。**调整为:** 写两个函数 plan() 和 execute(),然后在 Controller 层串联它们。 |
| **04-前端开发指南** | 定义了 PlanCard, ExecutionTree, ResultCard。 | 需要支持“咨询模式”和“执行模式”。 | **微调路由 (10%)**。 增加一个 /consult 页面(复用 Chat 组件。PlanCard 增加一个“仅下载方案”的按钮。 |
| **00/01 计划任务** | 定义了开发里程碑。 | 强调 Planner 先行。 | **无需调整**。 原计划也是先做 RAG/Planner再做 Executor。顺序本就一致。 |
## **3\. 为什么“双引擎”概念依然重要?(即使流程没变)**
既然流程一样,为什么还要提“双引擎”?是为了解决 **边界情况Corner Cases**
1. **无数据咨询 (The "No-Data" Problem)**
* 如果按照旧的 V1.3 思维,代码可能会写成 if (\!file) throw Error("请上传文件")。
* 引入“双引擎”概念后,后端代码会写成 if (\!file) return PlannerService.consult()。
* **这就是唯一的区别:允许 Planner 独立工作。**
2. **专家配置 (The "Config" Problem)**
* V1.3 计划里,工具的 Prompt 可能是写死在代码里的。
* V2.0 强调配置中心,提醒我们把 Prompt 放到数据库里,让专家能改。
## **4\. 最终执行建议:如何使用现有的 5 个文档?**
**请直接使用之前的 5 个文档进行开发,但在实施时遵循以下 3 条“解耦原则”:**
1. **后端开发原则**
* 不要把 Planner 的逻辑和 Executor 的逻辑混在一个 Class 里。请创建 src/modules/ssa/planner/ 和 src/modules/ssa/executor/ 两个文件夹。
2. **前端开发原则**
* 不要假设用户一定上传了文件。Chat 界面初始化时,允许 file 为空。
3. **专家配置原则**
* 按原计划优先使用 **Excel** 导入配置。这是最快落地的方案,不需要改架构。
**一句话总结:**
**架构不需要大改。V1.3 的开发计划是稳健的。所谓的“架构调整”,只是要求开发人员在写代码时,“手起刀落”把逻辑拆得更干净一点,方便未来复用,仅此而已。**

View File

@@ -1,10 +1,10 @@
# SSA-Pro MVP 开发计划总览
> **文档版本:** v1.3
> **文档版本:** v1.5
> **创建日期:** 2026-02-18
> **最后更新:** 2026-02-18纳入 V3.0 终极审查建议
> **最后更新:** 2026-02-18纳入专家配置体系 + 决策表匹配 + R代码库
> **项目代号:** SSA (Smart Statistical Analysis)
> **MVP 目标:** 打通完整闭环,上线 10 个核心统计工具
> **MVP 目标:** 打通完整闭环,上线 10 个核心统计工具,支持咨询模式
---
@@ -15,9 +15,11 @@
| 类别 | 内容 |
|------|------|
| **统计工具** | 10 个高频工具T检验、ANOVA、卡方、相关性等 |
| **双模式支持** | 🆕 **智能分析模式**(上传数据→执行)+ **咨询模式**无数据→SAP文档|
| **核心流程** | 上传数据 → AI规划 → 用户确认 → R执行 → 结果交付 |
| **交互能力** | 计划确认卡片、执行路径树、结果展示、代码下载 |
| **交互能力** | 计划确认卡片、执行路径树、结果展示、代码下载、🆕 SAP文档导出 |
| **智能能力** | RAG工具检索、Planner规划、Critic结果解读 |
| **配置中台** | 🆕 统计决策表 + R代码库 + 参数映射 + 护栏规则链 + 解读模板 |
| **数据安全** | LLM只看SchemaR服务处理真实数据 |
### 1.2 不包含内容 ❌
@@ -26,8 +28,9 @@
|------|------|---------|
| 50+ 工具量产 | MVP只做10个核心工具 | Phase 3 |
| 跨模块 Skills 化 | 不实现 Global Skill Registry | V2.0 |
| Word 报告导出 | 先实现代码下载 | Phase 3 |
| Word 报告导出 | 先实现代码下载 + SAP 文档 | Phase 3 |
| 大文件 OSS 传输 | MVP 限制 2MB 以内 | Phase 3 |
| 配置管理 UI | MVP 使用 Excel 导入 | V2.0 |
### 1.3 MVP 工具清单10个
@@ -46,65 +49,143 @@
---
## 2. 整体架构
## 2. 整体架构(双引擎 + 配置中台)
### 2.1 架构概念
```
┌─────────────────────────────────────────────────────────────────┐
前端 (React 19)
─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
│ │ 数据上传 │ │ 计划卡片 │ │ 执行路径 │ │ 结果展示 │
└─────────┘ └─────────┘ └─────────┘ └─────────┘
用户触点
┌─────────────────┐ ┌─────────────────┐
智能分析模式 │ │ 咨询模式 │
│ (上传数据+执行) │ │ (无数据,生成SAP) │
│ └────────┬────────┘ └────────┬────────┘ │
└────────────┼──────────────────────────┼─────────────────────────┘
│ │
▼ ▼
┌─────────────────────────────────────────────────────────────────┐
│ Planner (大脑) - Node.js │
│ ┌─────────┐ ┌───────────────┐ ┌─────────┐ ┌─────────┐ │
│ │ Rewriter│→ │🆕 决策表匹配 │→ │ Planner │→ │ Critic │ │
│ └─────────┘ │(Goal,Y,X,Design)│ └─────────┘ └─────────┘ │
│ └───────────────┘ │
│ 📌 只看 Schema四维匹配精准选工具支持有数据/无数据 │
└────────────────────────────┬────────────────────────────────────┘
HTTP API
┌────────────────────────────┴────────────────────────────────────┐
│ Node.js 后端 (Brain) │
┌──────────────────────────────────────────────────────────┐
│ SSA Orchestrator (编排服务)
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
│ │ Rewriter│→ │ RAG检索 │→ │ Planner │→ │ Critic │ │
│ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │
│ └──────────────────────────────────────────────────────────┘ │
│ 只看 Schema不看真实数据 │
└────────────────────────────┬────────────────────────────────────┘
│ HTTP (内网)
┌────────────────────────────┴────────────────────────────────────┐
│ R 统计服务 (Hand) │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ Plumber API Gateway │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ │ 护栏检查 │→ │ 核心计算 │→ │ 代码生成 │ │ │
│ │ └─────────┘ └─────────┘ └─────────┘ │ │
│ └──────────────────────────────────────────────────────────┘ │
│ 处理真实数据,网络隔离 │
(仅智能分析模式)
┌─────────────────────────────────────────────────────────────────┐
Executor (四肢) - R Docker
┌─────────┐ ┌─────────┐ ┌─────────┐
│ │ 护栏检查 │→ │ 核心计算 │→ │ 代码生成 │
└─────────┘ └─────────┘ └─────────┘
📌 处理真实数据,网络隔离
└─────────────────────────────────────────────────────────────────┘
┌────────────────────────────┴────────────────────────────────────┐
│ 🆕 配置中台 (Config Center) - 专家知识库 │
├─────────────────────────────────────────────────────────────────┤
│ 📊 Planner 配置 │
│ ┌─────────────────────────────────────────────────────────────┐│
│ │ 决策表: Goal_Type + Y_Type + X_Type + Design → Tool_Code ││
│ └─────────────────────────────────────────────────────────────┘│
│ 🔧 Executor 配置 │
│ ┌─────────────────────────────────────────────────────────────┐│
│ │ R代码库: 100+ 成熟脚本 │ 参数映射 │ 护栏规则链(Block/Warn/Switch)││
│ │ 输出定义 │ 解读模板 │ 代码交付模板 ││
│ └─────────────────────────────────────────────────────────────┘│
│ 📌 统计专家配置,系统动态加载,统一入口 run_analysis() │
└─────────────────────────────────────────────────────────────────┘
```
### 2.2 双模式流程
| 模式 | 数据要求 | 调用链 | 输出 |
|------|---------|--------|------|
| **智能分析** | ✅ 上传数据 | Planner → Executor | 结果 + R 代码 |
| **统计咨询** | ❌ 无需数据 | Planner only | SAP 文档Word |
### 2.3 代码目录结构(概念显性化)
```
backend/src/modules/ssa/
├── planner/ ← Planner 职责
│ ├── DataParserService.ts # 解析数据 Schema
│ ├── DecisionTableService.ts # 🆕 决策表匹配 (Goal,Y,X,Design)
│ ├── ToolRetrievalService.ts # RAG 检索(辅助)
│ ├── PlannerService.ts # 生成分析计划(有数据)
│ └── ConsultService.ts # 无数据咨询(生成 SAP
├── executor/ ← Executor 职责
│ └── RClientService.ts # 调用 R 服务
├── config/ ← 配置中台
│ ├── DecisionTableLoader.ts # 🆕 加载统计决策表
│ ├── RCodeLibraryService.ts # 🆕 R 代码库管理
│ ├── ParamMappingService.ts # 🆕 参数映射配置
│ ├── GuardrailConfigService.ts # 🆕 护栏规则链
│ └── ConfigValidatorService.ts # 配置校验
├── routes/ # API 路由
├── dto/ # 数据传输对象
└── types/ # 类型定义
```
### 2.4 🆕 专家配置文件结构
```
config/ssa/
├── decision_table.xlsx # 统计决策表Planner 用)
│ └── Sheet: Scenarios # Goal + Y + X + Design → Tool
├── r_scripts/ # 🆕 100+ 成熟 R 脚本
│ ├── t_test_ind.R
│ ├── wilcoxon.R
│ ├── anova_one.R
│ └── ...
├── tool_config.xlsx # 工具配置
│ ├── Sheet: Metadata # 工具基础信息
│ ├── Sheet: ParamMapping # JSON Key → R 参数名
│ ├── Sheet: Guardrails # 护栏规则链
│ ├── Sheet: OutputDef # 输出字段定义
│ └── Sheet: Interpretation # 结果解读模板
└── code_templates/ # 用户下载的代码模板
├── t_test.R.template
└── ...
```
---
## 3. 里程碑与时间线
### Phase 1骨架搭建Week 1-2
### Phase 1骨架搭建 + 配置中台Week 1-2
**目标:** 跑通 T 检验的 "Hello World"
**目标:** 跑通 T 检验 + 配置中台基础 + 决策表匹配
| 交付物 | 验收标准 |
|--------|---------|
| R Docker 镜像 | 本地可运行,健康检查通过 |
| Plumber API | POST /api/v1/skills/ST_T_TEST_IND 返回 JSON |
| Node.js 转发 | POST /api/v1/ssa/execute 调用 R 成功 |
| 数据库 Schema | tools_library, sessions, messages 表创建 |
| 前端骨架 | 基础页面框架,可上传文件 |
| 数据库 Schema | tools_library, sessions, messages, 🆕**r_code_library** 表创建 |
| 🆕 决策表加载 | 从 Excel 加载 (Goal,Y,X,Design) → Tool 映射 |
| 🆕 R 代码库管理 | 上传 R 脚本到数据库,统一 `run_analysis()` 入口 |
| 🆕 参数映射配置 | JSON Key → R 参数名映射可配置 |
| 🆕 护栏规则链 | Block/Warn/Switch 三种 Action 可配置 |
| 🆕 配置热加载 | Admin API `/config/reload` 触发配置更新 |
| 前端骨架 | 基础页面框架,🆕 **模式切换 Tab**(分析/咨询)|
### Phase 2智能规划与交互Week 3-4
### Phase 2智能规划与咨询模式Week 3-4
**目标:** 用户可与 AI 对话,确认后执行
**目标:** 决策表驱动规划 + 纯咨询模式双上线
| 交付物 | 验收标准 |
|--------|---------|
| RAG 检索 | 输入"两组差异"能返回 T 检验 |
| Planner | 生成正确的参数映射 JSON |
| 🆕 决策表匹配 | 根据 (Goal,Y,X,Design) 精准选工具RAG 辅助 |
| Planner(有数据) | 决策表 + Schema → 参数映射 JSON |
| 🆕 Planner无数据 | 决策表 + 用户描述 → SAP 文档 |
| 🆕 SAP 文档导出 | Word/Markdown 格式下载 |
| 🆕 结果解读模板 | 根据配置的解读模板生成论文级结论 |
| 计划确认卡片 | 前端展示,用户可修改参数 |
| 执行路径树 | 显示护栏检查步骤 |
| 执行路径树 | 显示护栏检查步骤(含 Action 类型)|
| 5 个工具 | T检验、配对T、ANOVA、卡方、相关性 |
### Phase 3完善与联调Week 5-6
@@ -116,22 +197,57 @@
| Critic 解读 | 生成严谨的统计结论 |
| 代码下载 | 用户可下载 .R 文件 |
| 10 个工具 | 全部上线并测试通过 |
| 端到端测试 | 10 个典型场景通过 |
| 🆕 配置验证 | Excel 导入时校验格式/必填/唯一性 |
| 端到端测试 | 10 个典型场景通过(含咨询模式)|
| SAE 部署 | R 服务部署成功 |
---
## 4. 核心 API 设计
### 4.1 会话与分析 API
```
POST /api/v1/ssa/sessions # 创建会话
POST /api/v1/ssa/sessions/:id/upload # 上传数据
POST /api/v1/ssa/sessions/:id/plan # 生成计划(不执行
POST /api/v1/ssa/sessions/:id/upload # 上传数据(智能分析模式)
POST /api/v1/ssa/sessions/:id/plan # 生成计划(有数据
POST /api/v1/ssa/sessions/:id/execute # 确认执行
GET /api/v1/ssa/sessions/:id/messages # 获取消息历史
GET /api/v1/ssa/sessions/:id/download-code # 下载代码
```
### 4.2 🆕 咨询模式 API
```
POST /api/v1/ssa/consult # 创建咨询会话(无数据)
POST /api/v1/ssa/consult/:id/chat # 咨询对话(多轮)
POST /api/v1/ssa/consult/:id/generate-sap # 生成 SAP 文档
GET /api/v1/ssa/consult/:id/download-sap # 下载 SAPWord/MD
```
### 4.3 🆕 配置中台 API
```
# 决策表配置
POST /api/v1/ssa/config/decision-table # 导入决策表 Excel
GET /api/v1/ssa/config/decision-table # 获取决策表
# R 代码库配置
POST /api/v1/ssa/config/r-scripts # 上传 R 脚本
GET /api/v1/ssa/config/r-scripts # 获取脚本列表
PUT /api/v1/ssa/config/r-scripts/:id # 更新脚本
# 工具配置
POST /api/v1/ssa/config/tool-config # 导入工具配置 Excel
GET /api/v1/ssa/config/tools # 获取工具列表
GET /api/v1/ssa/config/tools/:code/params # 获取参数映射
GET /api/v1/ssa/config/tools/:code/guardrails # 获取护栏规则
# 通用
POST /api/v1/ssa/config/reload # 热加载所有配置Admin
GET /api/v1/ssa/config/validate # 校验配置文件
```
---
## 5. 依赖与集成
@@ -154,7 +270,9 @@ GET /api/v1/ssa/sessions/:id/download-code # 下载代码
| R Docker 镜像 | 基于 rocker/r-ver:4.3,含 Plumber + renv |
| R 统计服务 | SAE 新应用,**VPC 内网通信** |
| SSA 前端模块 | `frontend-v2/src/modules/ssa/` |
| SSA 后端模块 | `backend/src/modules/ssa/` |
| SSA 后端模块 | `backend/src/modules/ssa/`(按 planner/executor/config 组织)|
| 🆕 配置中台 | Excel 配置文件 + ConfigLoaderService |
| 🆕 SAP 生成器 | ConsultService + Word 导出 |
### 5.3 关键配置要求

View File

@@ -1,9 +1,11 @@
# SSA-Pro MVP 任务清单与进度追踪
> **文档版本:** v1.3
> **文档版本:** v1.6
> **创建日期:** 2026-02-18
> **最后更新:** 2026-02-18纳入 V3.0 终极审查建议
> **最后更新:** 2026-02-19T 检验端到端测试通过
> **更新频率:** 每日站会后更新
>
> **当前进度:** Phase 1 核心完成 ~85%,配置中台待开发
---
@@ -18,60 +20,84 @@
---
## Phase 1骨架搭建Week 1-2
## Phase 1骨架搭建 + 配置中台Week 1-2
**里程碑目标:** T 检验 API 端到端跑通
**里程碑目标:** T 检验 API 端到端跑通 + 配置中台基础
### R 服务任务
| 状态 | 任务 | 预估 | 备注 |
|------|------|------|------|
| | 创建 `r-statistics-service/` 目录结构 | 2h | 含 templates/, fixtures/ 目录 |
| | 初始化 renv 并生成 `renv.lock` | 1h | **锁定包版本** |
| | 编写 Dockerfile基于 rocker/r-ver:4.3 | 2h | 使用 renv::restore() |
| | 🆕 Dockerfile 配置 OSS 环境变量 | 1h | **ENV 注入,非硬编码** |
| | 安装 glue 包,创建代码模板文件 | 2h | **替代 paste0 拼接** |
| | 🆕 实现 `data_loader.R`(混合协议) | 3h | **支持 inline/OSS/DEV_MODE** |
| | 🆕 实现 `result_formatter.R`p_value_fmt | 1h | **APA 格式化** |
| | 实现 `plumber.R` 入口文件 | 2h | 健康检查 + 动态路由 |
| | 🆕 plumber.R 添加 Debug 模式支持 | 1h | **保留临时文件排查** |
| | 定义错误码枚举error_codes.R | 1h | **业务/系统错误分离** |
| | 🆕 扩展错误码映射表map_r_error | 1h | **R 错误 → 用户友好提示** |
| | 🆕 代码模板头部添加依赖安装脚本 | 0.5h | **用户本地可运行** |
| | 🆕 创建 `tests/fixtures/` 标准测试数据 | 2h | **normal/skewed/missing** |
| | 实现 T 检验 WrapperST_T_TEST_IND | 4h | 含护栏 + glue + 大样本优化 |
| | 本地 Docker 测试通过 | 2h | |
| | 创建 `r-statistics-service/` 目录结构 | 2h | 含 templates/, fixtures/ 目录 |
| | 初始化 renv 并生成 `renv.lock` | 1h | **锁定包版本** |
| | 编写 Dockerfile基于 rocker/r-ver:4.3 | 2h | 使用 renv::restore() |
| | 🆕 Dockerfile 配置 OSS 环境变量 | 1h | **ENV 注入,非硬编码** |
| | 安装 glue 包,创建代码模板文件 | 2h | **已在 T 检验中使用** |
| | 🆕 实现 `data_loader.R`(混合协议) | 3h | **支持 inline/OSS/DEV_MODE** |
| | 🆕 实现 `result_formatter.R`p_value_fmt | 1h | **APA 格式化** |
| | 实现 `plumber.R` 入口文件 | 2h | 健康检查 + 动态路由 |
| | 🆕 plumber.R 添加 Debug 模式支持 | 1h | **DEV_MODE 环境变量** |
| | 定义错误码枚举error_codes.R | 1h | **业务/系统错误分离** |
| | 🆕 扩展错误码映射表map_r_error | 1h | **R 错误 → 用户友好提示** |
| | 🆕 代码模板头部添加依赖安装脚本 | 0.5h | **reproducible_code 中包含** |
| | 🆕 创建 `tests/fixtures/` 标准测试数据 | 2h | **normal/skewed/missing** |
| | 实现 T 检验 WrapperST_T_TEST_IND | 4h | 含护栏 + glue + 缺失值处理 |
| | 本地 Docker 测试通过 | 2h | **2026-02-19 端到端测试通过** |
### 后端任务
| 状态 | 任务 | 预估 | 备注 |
|------|------|------|------|
| | 创建 `backend/src/modules/ssa/` 目录结构 | 1h | |
| | 设计并创建数据库 SchemaPrisma | 3h | 4张表 |
| | 执行 `prisma migrate dev` | 0.5h | |
| | 安装 json-repair 和 zod 依赖 | 0.5h | **LLM 输出容错** |
| | 实现 `RClientService`调用 R 服务 | 3h | 超时 120s |
| | 🆕 RClientService 添加 502/504 友好处理 | 0.5h | **R 崩溃用户提示** |
| | 创建 `backend/src/modules/ssa/` 目录结构 | 1h | **按 planner/executor/config 组织** |
| | 设计并创建数据库 SchemaPrisma | 3h | 9张表(含配置中台) |
| | 执行 `prisma migrate dev` | 0.5h | 已创建迁移文件 |
| 🔄 | 安装 json-repair 和 zod 依赖 | 0.5h | **LLM 输出容错** |
| | 实现 `RClientService`executor/ | 3h | 超时 120s |
| | 🆕 RClientService 添加 502/504 友好处理 | 0.5h | **错误友好提示已实现** |
| ⬜ | 🆕 DataParserService 分类变量隐私保护 | 1h | **稀有值 < 5 隐藏** |
| | 实现 `POST /api/v1/ssa/execute` 存根 | 2h | 先做转发 |
| | 注册路由到 `index.ts` | 0.5h | |
| | 实现 `POST /api/v1/ssa/execute` 存根 | 2h | **完整实现,含错误处理** |
| | 注册路由到 `index.ts` | 0.5h | |
| ✅ | 🆕 实现 DataParserService数据解析 | 2h | **类型推断 + 缺失值处理** |
| ✅ | 🆕 实现分析计划生成 API | 2h | **变量智能匹配** |
| ✅ | 🆕 实现代码下载 API | 1h | **动态文件名** |
### 🆕 配置中台任务
| 状态 | 任务 | 预估 | 备注 |
|------|------|------|------|
| 🔄 | 🆕 设计统计决策表 Excel 模板 | 2h | **Goal + Y + X + Design → Tool** |
| ⬜ | 🆕 实现 `DecisionTableLoader` | 3h | **四维匹配逻辑** |
| ✅ | 🆕 设计 R 代码库数据库表 | 1h | **r_code_library 表已创建** |
| ⬜ | 🆕 实现 `RCodeLibraryService` | 3h | **脚本上传/版本管理** |
| 🔄 | 🆕 定义工具配置 Excel 模板5个Sheet | 3h | **元数据/参数映射/护栏/输出/解读** |
| ⬜ | 🆕 实现 `ParamMappingService` | 2h | **JSON Key → R 参数名** |
| ⬜ | 🆕 实现 `GuardrailConfigService` | 3h | **Block/Warn/Switch 三种 Action** |
| ⬜ | 🆕 实现 `InterpretationService` | 2h | **解读模板填空** |
| ⬜ | 🆕 实现 `ConfigValidatorService` | 2h | **必填/格式/唯一性校验** |
| ✅ | 🆕 实现配置热加载 API | 1h | **POST /config/reload 路由已创建** |
| ⬜ | 🆕 上传 T 检验 R 脚本 + 配置 | 2h | **跑通完整流程** |
### 前端任务
| 状态 | 任务 | 预估 | 备注 |
|------|------|------|------|
| | 创建 `frontend-v2/src/modules/ssa/` 目录结构 | 1h | |
| | 注册到 `moduleRegistry.ts` | 0.5h | |
| | 实现基础页面框架SSAWorkspace | 3h | 参考原型图 |
| | 实现左侧边栏组件 | 2h | |
| | 实现数据上传组件DataUploader | 3h | |
| | 构造 Mock 数据用于组件开发 | 1h | |
| | 创建 `frontend-v2/src/modules/ssa/` 目录结构 | 1h | 含 components/hooks/stores/types |
| | 注册到 `moduleRegistry.ts` | 0.5h | **已激活模块** |
| | 实现基础页面框架SSAWorkspace | 3h | 参考原型图 |
| | 🆕 实现模式切换 Tab智能分析/统计咨询) | 2h | **双模式入口** |
| | 实现左侧边栏组件 | 2h | 含数据信息展示 |
| | 实现数据上传组件DataUploader | 3h | Drag & Drop |
| ✅ | 🆕 实现结果展示组件ResultCard + APATable | 3h | **三线表 + 图表** |
| ✅ | 🆕 实现执行进度组件ExecutionTrace | 2h | **步骤状态展示** |
| ✅ | 🆕 实现代码下载功能 | 1h | **从后端获取文件名** |
| ✅ | 🆕 实现 Zustand Store | 2h | **会话状态管理** |
| ✅ | 🆕 实现 useAnalysis Hook | 2h | **上传/计划/执行/下载** |
---
## Phase 2智能规划与交互Week 3-4
## Phase 2智能规划与咨询模式Week 3-4
**里程碑目标:** 用户可与 AI 对话,确认后执行
**里程碑目标:** 决策表驱动规划 + 咨询模式上线
### R 服务任务
@@ -81,18 +107,27 @@
| ⬜ | 实现单因素 ANOVAST_ANOVA_ONE | 3h | |
| ⬜ | 实现卡方检验ST_CHI_SQUARE | 3h | |
| ⬜ | 实现相关性分析ST_CORRELATION | 3h | |
| ⬜ | 🆕 所有 R 脚本统一 `run_analysis()` 入口 | 2h | **专家规范** |
| ⬜ | 实现通用护栏函数utils/guardrails.R | 2h | |
| ⬜ | 为 5 个工具编写元数据 YAML | 2h | |
| ⬜ | 🆕 护栏支持 Block/Warn/Switch Action | 2h | **三种响应策略** |
| ⬜ | 🆕 为 5 个工具上传 R 脚本 + Excel 配置 | 3h | **专家完整配置** |
### 后端任务
| 状态 | 任务 | 预估 | 备注 |
|------|------|------|------|
| ⬜ | 实现 `ToolRetrievalService`RAG 检索 | 4h | 复用 VectorSearchService |
| ⬜ | 导入 5 个工具元数据到 pgvector | 2h | |
| ⬜ | 🆕 实现 `DecisionTableService`planner/ | 4h | **四维匹配选工具** |
| ⬜ | 实现 `ToolRetrievalService`planner/ | 3h | 复用 VectorSearchService辅助 |
| ⬜ | 🆕 决策表 + RAG 融合策略 | 2h | **决策表优先RAG 兜底** |
| ⬜ | 注册 Prompt 到 capability_schema | 2h | 4 个 Prompt |
| ⬜ | 实现 `PlannerService`LLM 调用 | 4h | 含 json-repair + Zod 校验 |
| ⬜ | 实现 `PlannerService`planner/,有数据 | 4h | 含 json-repair + Zod 校验 |
| ⬜ | 🆕 PlannerService 调用决策表匹配 | 2h | **Goal → Tool 精准匹配** |
| ⬜ | 🆕 实现 `ConsultService`planner/,无数据) | 4h | **基于决策表推理生成 SAP** |
| ⬜ | 🆕 实现 `SAPGeneratorService`SAP 文档生成) | 3h | **Markdown → Word 导出** |
| ⬜ | 🆕 实现结果解读InterpretationService | 3h | **基于配置模板生成论文级结论** |
| ⬜ | 实现 `POST /api/v1/ssa/sessions/:id/plan` | 3h | |
| ⬜ | 🆕 实现 `POST /api/v1/ssa/consult/:id/chat` | 2h | **咨询对话** |
| ⬜ | 🆕 实现 `POST /api/v1/ssa/consult/:id/generate-sap` | 2h | **生成 SAP** |
| ⬜ | 实现会话管理 APICRUD | 3h | |
| ⬜ | 实现 Brain-Hand 数据隔离逻辑 | 2h | Schema 给 LLMData 给 R |
| ⬜ | DataParserService 增加小样本隐私保护 | 1h | N<10 时模糊化 Min/Max |
@@ -103,9 +138,12 @@
|------|------|------|------|
| ⬜ | 实现 Chat 消息流组件 | 4h | 复用 AIStreamChat |
| ⬜ | 实现计划确认卡片PlanCard | 4h | 参考原型图 |
| ⬜ | 🆕 PlanCard 增加"仅下载方案"按钮 | 1h | **咨询模式** |
| ⬜ | 实现执行路径树ExecutionTrace | 3h | 动画效果 |
| ⬜ | 🆕 实现咨询模式 UIConsultChat | 3h | **无数据对话** |
| ⬜ | 🆕 实现 SAP 预览/下载组件 | 2h | **Word/MD 下载** |
| ⬜ | 实现 API 对接api.ts | 2h | |
| ⬜ | 实现 Zustand Store | 2h | |
| ⬜ | 实现 Zustand Store | 2h | **含 mode 切换状态** |
---
@@ -166,10 +204,12 @@
| Phase | 任务总数 | 已完成 | 进度 |
|-------|---------|--------|------|
| Phase 1 | 21 | 0 | 0% |
| Phase 2 | 20 | 0 | 0% |
| Phase 3 | 21 | 0 | 0% |
| **总计** | **62** | **0** | **0%** |
| Phase 1 | 40 | 34 | 85% |
| Phase 2 | 30 | 0 | 0% |
| Phase 3 | 22 | 0 | 0% |
| **总计** | **92** | **34** | **37%** |
> **v1.6 更新**Phase 1 核心流程完成T 检验端到端测试通过2026-02-19
---
@@ -183,13 +223,21 @@
## 每日站会记录
### 2026-02-xx
### 2026-02-19
**昨日完成:**
-
**完成**
- ✅ R 服务 T 检验端到端测试通过
- ✅ 修复缺失值导致分组变量识别为 3 组的问题R 服务自动过滤 NA
- ✅ 修复 DataParserService 类型推断0/1 数字列识别为分类变量)
- ✅ 修复后端 R 服务错误响应处理(返回 422 + user_hint
- ✅ 修复前端代码下载文件名(从 Content-Disposition 提取)
- ✅ 修复前端用户会话隔离(组件挂载时重置 store
- ✅ 完成前端模块注册,激活智能统计分析入口
**今日计划**
-
**待解决**
- 配置中台功能待开发
- json-repair 和 zod 依赖待安装
- DataParserService 隐私保护待实现
**阻塞问题**
-
**下一步**
- 进入 Phase 2 或完善 Phase 1 配置中台

View File

@@ -1,8 +1,8 @@
# SSA-Pro R 服务开发指南
> **文档版本:** v1.3
> **文档版本:** v1.5
> **创建日期:** 2026-02-18
> **最后更新:** 2026-02-18纳入 V3.0 终极审查建议
> **最后更新:** 2026-02-18纳入专家配置体系 + 统一入口函数
> **目标读者:** R 统计工程师
---
@@ -15,31 +15,51 @@ r-statistics-service/
├── renv.lock # 📌 包版本锁定文件
├── .Rprofile # renv 初始化
├── plumber.R # Plumber 入口
├── tools/ # 统计工具目录
│ ├── ST_T_TEST_IND.R
│ ├── ST_T_TEST_PAIRED.R
│ ├── ST_ANOVA_ONE.R
── ...
├── templates/ # 📌 代码模板目录glue
├── tools/ # 🆕 专家上传的 R 脚本(统一 run_analysis 入口)
│ ├── t_test_ind.R # 独立样本 T 检验
│ ├── t_test_paired.R # 配对样本 T 检验
│ ├── anova_one.R # 单因素方差分析
── wilcoxon.R # Wilcoxon 秩和检验
│ └── ... # 📌 约 100 个成熟脚本
├── templates/ # 📌 代码交付模板glue 格式)
│ ├── t_test.R.template
│ ├── anova.R.template
│ └── ...
├── utils/
│ ├── data_loader.R # 🆕 混合数据协议加载器
│ ├── guardrails.R # 护栏函数库
│ ├── data_loader.R # 混合数据协议加载器
│ ├── guardrails.R # 🆕 护栏函数库(支持 Block/Warn/Switch
│ ├── code_generator.R # 代码生成工具(使用 glue
│ ├── result_formatter.R # 🆕 结果格式化p_value_fmt
│ ├── result_formatter.R # 结果格式化p_value_fmt
│ ├── interpretation.R # 🆕 结果解读(基于配置模板)
│ └── error_codes.R # 📌 错误码定义
├── metadata/ # 工具元数据
│ └── tools.yaml # 所有工具定义
├── metadata/ # 工具元数据(由配置中台管理)
│ └── tools.yaml # 备用配置
└── tests/
├── test_tools.R # 单元测试
└── fixtures/ # 🆕 标准测试数据集
└── fixtures/ # 标准测试数据集
├── normal_data.csv
├── skewed_data.csv
└── missing_data.csv
```
### 1.1 🆕 专家 R 脚本规范
> **核心要求**:所有脚本必须使用统一入口函数 `run_analysis(input)`
```r
# 文件头部注释(必填)
#' @tool_code ST_T_TEST_IND
#' @name 独立样本 T 检验
#' @version 1.0.0
#' @description 比较两组独立样本的均值差异
#' @author 统计学专家团队
# 📌 统一入口函数(所有脚本必须实现)
run_analysis <- function(input) {
# ... 实现逻辑 ...
}
```
---
## 2. Dockerfile 模板
@@ -725,25 +745,46 @@ generate_boxplot <- function(df, group_var, value_var, tmp_files_ref) {
# 🆕 大样本优化阈值
LARGE_SAMPLE_THRESHOLD <- 5000
# 正态性检验(🆕 大样本优化)
check_normality <- function(values, alpha = 0.05) {
# 🆕 护栏 Action 类型
ACTION_BLOCK <- "Block" # 阻止执行
ACTION_WARN <- "Warn" # 警告但继续
ACTION_SWITCH <- "Switch" # 切换到备选方法
# 🆕 护栏检查结果结构
# list(
# passed = TRUE/FALSE,
# action = "Block" | "Warn" | "Switch",
# action_target = "ST_XXX" | NULL,
# p_value = 0.05,
# reason = "描述"
# )
# 正态性检验(🆕 支持三种 Action
check_normality <- function(values, alpha = 0.05, action = ACTION_SWITCH, action_target = NULL) {
n <- length(values)
# 样本量过小
if (n < 3) {
return(list(passed = TRUE, reason = "样本量过小,跳过正态性检验", skipped = TRUE))
return(list(
passed = TRUE,
action = NULL,
action_target = NULL,
reason = "样本量过小,跳过正态性检验",
skipped = TRUE
))
}
# 🆕 大样本优化N > 5000 时使用抽样检验
if (n > LARGE_SAMPLE_THRESHOLD) {
# 抽取 1000 个样本进行检验
set.seed(42) # 保证可重复性
set.seed(42)
sampled_values <- sample(values, 1000)
test <- shapiro.test(sampled_values)
passed <- test$p.value >= alpha
return(list(
passed = passed,
action = if (passed) NULL else action,
action_target = if (passed) NULL else action_target,
p_value = test$p.value,
reason = glue("大样本(N={n})抽样检验,{if (passed) '满足正态性' else '不满足正态性'}"),
sampled = TRUE,
@@ -757,6 +798,8 @@ check_normality <- function(values, alpha = 0.05) {
return(list(
passed = passed,
action = if (passed) NULL else action,
action_target = if (passed) NULL else action_target,
p_value = test$p.value,
reason = if (passed) "满足正态性" else "不满足正态性",
sampled = FALSE
@@ -764,7 +807,7 @@ check_normality <- function(values, alpha = 0.05) {
}
# 方差齐性检验 (Levene)
check_homogeneity <- function(df, group_var, value_var, alpha = 0.05) {
check_homogeneity <- function(df, group_var, value_var, alpha = 0.05, action = ACTION_WARN) {
library(car)
formula <- as.formula(paste(value_var, "~", group_var))
@@ -774,20 +817,52 @@ check_homogeneity <- function(df, group_var, value_var, alpha = 0.05) {
return(list(
passed = passed,
action = if (passed) NULL else action,
p_value = p_val,
reason = if (passed) "方差齐性满足" else "方差不齐性"
))
}
# 样本量检验
check_sample_size <- function(n, min_required = 30) {
check_sample_size <- function(n, min_required = 30, action = ACTION_BLOCK) {
passed <- n >= min_required
return(list(
passed = passed,
action = if (passed) NULL else action,
n = n,
reason = if (passed) "样本量充足" else paste0("样本量不足, 需要至少 ", min_required)
))
}
# 🆕 执行护栏链(按 check_order 顺序执行)
run_guardrail_chain <- function(input, guardrail_configs) {
for (config in guardrail_configs) {
check_func <- get(config$check_code)
result <- do.call(check_func, list(
input,
action = config$action_type,
action_target = config$action_target
))
if (!result$passed) {
if (result$action == ACTION_BLOCK) {
return(list(
status = "blocked",
reason = result$reason
))
} else if (result$action == ACTION_SWITCH) {
return(list(
status = "switch",
target_tool = result$action_target,
reason = result$reason
))
}
# WARN: 记录警告但继续
}
}
return(list(status = "passed"))
}
```
---

View File

@@ -1,8 +1,8 @@
# SSA-Pro 前端开发指南
> **文档版本:** v1.3
> **文档版本:** v1.5
> **创建日期:** 2026-02-18
> **最后更新:** 2026-02-18纳入 V3.0 终极审查建议
> **最后更新:** 2026-02-18纳入专家配置体系 + 护栏 Action 展示
> **目标读者:** 前端工程师
> **原型参考:** `03-UI设计/智能统计分析V2.html`
@@ -19,7 +19,8 @@ frontend-v2/src/modules/ssa/
│ ├── layout/
│ │ ├── SSASidebar.tsx # 左侧边栏
│ │ ├── SSAHeader.tsx # 顶部标题栏
│ │ ── SSAInputArea.tsx # 底部输入区
│ │ ── SSAInputArea.tsx # 底部输入区
│ │ └── ModeSwitch.tsx # 🆕 模式切换 Tab
│ ├── chat/
│ │ ├── MessageList.tsx # 消息流容器
│ │ ├── SystemMessage.tsx # 系统消息气泡
@@ -31,44 +32,59 @@ frontend-v2/src/modules/ssa/
│ │ ├── PlanCard.tsx # 分析计划确认卡片 ⭐
│ │ ├── ExecutionTrace.tsx # 执行路径树 ⭐
│ │ ├── ExecutionProgress.tsx# 📌 执行进度动画 ⭐
│ │ ── ResultCard.tsx # 结果报告卡片 ⭐
│ │ ── ResultCard.tsx # 结果报告卡片 ⭐
│ │ └── SAPPreview.tsx # 🆕 SAP 文档预览/下载
│ ├── consult/ # 🆕 咨询模式组件
│ │ ├── ConsultChat.tsx # 无数据对话界面
│ │ └── SAPDownloadButton.tsx# SAP 下载按钮
│ └── common/
│ ├── APATable.tsx # 三线表组件
│ └── PlotViewer.tsx # 图表查看器
├── hooks/
│ ├── useSSASession.ts # 会话管理 Hook
── useSSAExecution.ts # 执行控制 Hook
── useSSAExecution.ts # 执行控制 Hook
│ └── useSSAConsult.ts # 🆕 咨询模式 Hook
├── store/
│ └── ssaStore.ts # Zustand Store
│ └── ssaStore.ts # Zustand Store(含 mode 状态)
├── api/
│ └── ssaApi.ts # API 封装
│ └── ssaApi.ts # API 封装(含咨询 API
├── types/
│ └── index.ts # 类型定义
└── styles/
└── ssa.css # 模块样式
```
### 1.1 🆕 双模式设计原则
| 原则 | 说明 |
|------|------|
| **模式切换** | 顶部 Tab 切换"智能分析"/"统计咨询" |
| **无数据友好** | 咨询模式不要求上传数据 |
| **SAP 导出** | 咨询完成后可下载 Word/Markdown |
---
## 2. 原型图核心元素解析
根据 `智能统计分析V2.html` 原型,需实现以下核心 UI
### 2.1 整体布局
### 2.1 整体布局(含模式切换)
```
┌─────────────────────────────────────────────────────────────────┐
│ ┌───────────┐ ┌─────────────────────────────────────────────┐ │
│ │ │ │ Header (会话标题) │ │
│ │ Sidebar │ ├─────────────────────────────────────────────┤
│ │ │ │ │
│ │ - 导入数据│ │ Chat Flow (消息流) │ │
│ │ - 新会话 │ │ │ │
│ │ - 历史 │ │ - SystemMessage (欢迎/上传引导) │ │
│ │ │ │ 🆕 [智能分析] [统计咨询] ← 模式切换 Tab │ │
│ │ Sidebar │ │ Header (会话标题) │
│ │ │ ├─────────────────────────────────────────────┤
│ │ - 导入数据│ │ │ │
│ │ - 新会话 │ │ Chat Flow (消息流) │ │
│ │ - 历史 │ │ │ │
│ │ │ │ - SystemMessage (欢迎/上传引导) │ │
│ │ │ │ - UserMessage (用户输入) │ │
│ │ │ │ - PlanCard (计划确认) │ │
│ │ ─────── │ │ - ExecutionTrace (执行路径) │ │
│ │ 数据状态 │ │ - ResultCard (结果报告) │ │
│ │ (分析模式) │ │ - 🆕 SAPPreview (咨询模式) │ │
│ │ │ │ │ │
│ │ │ ├─────────────────────────────────────────────┤ │
│ │ │ │ InputArea (输入框 + 发送按钮) │ │
@@ -214,9 +230,11 @@ import { CheckCircleFilled, ExclamationCircleFilled,
interface TraceStep {
id: string;
label: string;
status: 'success' | 'warning' | 'error' | 'running' | 'pending';
status: 'success' | 'warning' | 'error' | 'running' | 'pending' | 'switched'; // 🆕 switched
detail?: string;
subLabel?: string;
actionType?: 'Block' | 'Warn' | 'Switch'; // 🆕 护栏 Action 类型
switchTarget?: string; // 🆕 Switch 目标工具
}
interface ExecutionTraceProps {
@@ -232,12 +250,32 @@ export const ExecutionTrace: React.FC<ExecutionTraceProps> = ({ steps }) => {
return <ExclamationCircleFilled className="text-amber-500" />;
case 'error':
return <ExclamationCircleFilled className="text-red-500" />;
case 'switched': // 🆕 方法切换
return <SwapOutlined className="text-blue-500" />;
case 'running':
return <LoadingOutlined className="text-blue-500" spin />;
default:
return <div className="w-4 h-4 rounded-full bg-slate-200" />;
}
};
// 🆕 获取 Action 类型标签
const getActionTag = (step: TraceStep) => {
if (!step.actionType) return null;
const tagStyles = {
'Block': 'bg-red-100 text-red-700 border-red-200',
'Warn': 'bg-amber-100 text-amber-700 border-amber-200',
'Switch': 'bg-blue-100 text-blue-700 border-blue-200'
};
return (
<span className={`ml-2 px-1.5 py-0.5 text-xs rounded border ${tagStyles[step.actionType]}`}>
{step.actionType}
{step.switchTarget && <span className="ml-1"> {step.switchTarget}</span>}
</span>
);
};
return (
<div className="bg-white border border-slate-200 rounded-xl p-4 shadow-sm">
@@ -641,26 +679,39 @@ export const APATable: React.FC<APATableProps> = ({ columns, data }) => {
---
## 4. Zustand Store
## 4. Zustand Store(含模式切换)
```typescript
// store/ssaStore.ts
import { create } from 'zustand';
// 🆕 模式类型
type SSAMode = 'analysis' | 'consult';
interface Message {
id: string;
role: 'user' | 'assistant' | 'system';
contentType: 'text' | 'plan' | 'result' | 'trace';
contentType: 'text' | 'plan' | 'result' | 'trace' | 'sap'; // 🆕 增加 sap 类型
content: any;
createdAt: string;
}
// 🆕 SAP 文档类型
interface SAPDocument {
title: string;
sections: Array<{ heading: string; content: string }>;
recommendedTools: string[];
}
interface SSAState {
// 🆕 模式
mode: SSAMode;
// 会话
sessionId: string | null;
sessionTitle: string;
// 数据
// 数据(分析模式)
dataLoaded: boolean;
dataSchema: object | null;
dataFileName: string;
@@ -674,17 +725,25 @@ interface SSAState {
isExecuting: boolean;
currentPlan: object | null;
// 🆕 咨询模式状态
currentSAP: SAPDocument | null;
isGeneratingSAP: boolean;
// Actions
setMode: (mode: SSAMode) => void; // 🆕
setSession: (id: string, title?: string) => void;
setDataLoaded: (schema: object, fileName: string, rowCount: number) => void;
addMessage: (message: Omit<Message, 'id' | 'createdAt'>) => void;
setPlanning: (planning: boolean) => void;
setExecuting: (executing: boolean) => void;
setCurrentPlan: (plan: object | null) => void;
setCurrentSAP: (sap: SAPDocument | null) => void; // 🆕
setGeneratingSAP: (generating: boolean) => void; // 🆕
reset: () => void;
}
export const useSSAStore = create<SSAState>((set, get) => ({
mode: 'analysis', // 🆕 默认分析模式
sessionId: null,
sessionTitle: '新会话',
dataLoaded: false,
@@ -695,6 +754,19 @@ export const useSSAStore = create<SSAState>((set, get) => ({
isPlanning: false,
isExecuting: false,
currentPlan: null,
currentSAP: null, // 🆕
isGeneratingSAP: false, // 🆕
// 🆕 切换模式
setMode: (mode) => set({
mode,
// 切换模式时重置会话
sessionId: null,
messages: [],
dataLoaded: false,
currentPlan: null,
currentSAP: null
}),
setSession: (id, title = '新会话') => set({ sessionId: id, sessionTitle: title }),
@@ -719,8 +791,11 @@ export const useSSAStore = create<SSAState>((set, get) => ({
setPlanning: (planning) => set({ isPlanning: planning }),
setExecuting: (executing) => set({ isExecuting: executing }),
setCurrentPlan: (plan) => set({ currentPlan: plan }),
setCurrentSAP: (sap) => set({ currentSAP: sap }), // 🆕
setGeneratingSAP: (generating) => set({ isGeneratingSAP: generating }), // 🆕
reset: () => set({
mode: 'analysis',
sessionId: null,
sessionTitle: '新会话',
dataLoaded: false,
@@ -730,14 +805,16 @@ export const useSSAStore = create<SSAState>((set, get) => ({
messages: [],
isPlanning: false,
isExecuting: false,
currentPlan: null
currentPlan: null,
currentSAP: null,
isGeneratingSAP: false
})
}));
```
---
## 5. API 封装
## 5. API 封装(含咨询模式)
```typescript
// api/ssaApi.ts
@@ -746,6 +823,8 @@ import { apiClient } from '@/common/api/client';
const BASE = '/api/v1/ssa';
export const ssaApi = {
// ==================== 智能分析模式 ====================
// 会话
createSession: () =>
apiClient.post<{ id: string }>(`${BASE}/sessions`),
@@ -780,6 +859,50 @@ export const ssaApi = {
apiClient.get(`${BASE}/sessions/${sessionId}/download-code/${messageId}`, {
responseType: 'blob'
}),
// ==================== 🆕 咨询模式 ====================
// 创建咨询会话(无数据)
createConsultSession: () =>
apiClient.post<{ id: string }>(`${BASE}/consult`),
// 咨询对话
consultChat: (sessionId: string, message: string) =>
apiClient.post<{ response: string }>(`${BASE}/consult/${sessionId}/chat`, { message }),
// 生成 SAP 文档
generateSAP: (sessionId: string) =>
apiClient.post<{
title: string;
sections: Array<{ heading: string; content: string }>;
recommendedTools: string[];
}>(`${BASE}/consult/${sessionId}/generate-sap`),
// 下载 SAPWord/Markdown
downloadSAP: (sessionId: string, format: 'word' | 'markdown' = 'word') =>
apiClient.get(`${BASE}/consult/${sessionId}/download-sap`, {
params: { format },
responseType: 'blob'
}),
// ==================== 🆕 配置中台 ====================
// 导入配置
importConfig: (file: File) => {
const formData = new FormData();
formData.append('file', file);
return apiClient.post(`${BASE}/config/import`, formData, {
headers: { 'Content-Type': 'multipart/form-data' }
});
},
// 获取工具列表
getConfigTools: () =>
apiClient.get(`${BASE}/config/tools`),
// 热加载配置Admin
reloadConfig: () =>
apiClient.post(`${BASE}/config/reload`),
};
```
@@ -864,15 +987,301 @@ export const ssaRoutes = [
| 组件 | 功能 | 状态 |
|------|------|------|
| SSASidebar | 导入数据、新建会话、历史列表、数据状态 | ⬜ |
| 🆕 **ModeSwitch** | **模式切换 Tab智能分析/统计咨询)** | ⬜ |
| DataUploader | 拖拽/点击上传,进度显示 | ⬜ |
| MessageList | 消息流滚动,自动滚底 | ⬜ |
| PlanCard | 参数展示、护栏提示、确认/修改按钮 | ⬜ |
| 🆕 PlanCard | **增加"仅下载方案"按钮(咨询模式)** | ⬜ |
| ExecutionTrace | 步骤树、状态图标、连接线 | ⬜ |
| **ExecutionProgress** | **📌 执行中进度动画,缓解等待焦虑** | ⬜ |
| ResultCard | 三线表、图表、解读、下载按钮 | ⬜ |
| APATable | APA 格式表格样式 | ⬜ |
| Zustand Store | 状态管理 | ⬜ |
| API 对接 | 所有接口联调,**超时 120s** | ⬜ |
| 🆕 **ConsultChat** | **无数据咨询对话界面** | ⬜ |
| 🆕 **SAPPreview** | **SAP 文档预览/下载** | ⬜ |
| 🆕 **SAPDownloadButton** | **Word/Markdown 下载选择** | ⬜ |
| Zustand Store | 状态管理,**含 mode 切换** | ⬜ |
| API 对接 | 所有接口联调,**含咨询 API** | ⬜ |
---
## 9. 🆕 新增组件实现
### 9.1 ModeSwitch模式切换 Tab
```tsx
// components/layout/ModeSwitch.tsx
import React from 'react';
import { Segmented } from 'antd';
import { BarChartOutlined, MessageOutlined } from '@ant-design/icons';
import { useSSAStore } from '../../store/ssaStore';
export const ModeSwitch: React.FC = () => {
const { mode, setMode } = useSSAStore();
return (
<Segmented
value={mode}
onChange={(value) => setMode(value as 'analysis' | 'consult')}
options={[
{
label: (
<div className="flex items-center gap-2 px-2">
<BarChartOutlined />
<span></span>
</div>
),
value: 'analysis',
},
{
label: (
<div className="flex items-center gap-2 px-2">
<MessageOutlined />
<span></span>
</div>
),
value: 'consult',
},
]}
className="bg-slate-100"
/>
);
};
```
### 9.2 ConsultChat无数据咨询界面
```tsx
// components/consult/ConsultChat.tsx
import React, { useState } from 'react';
import { Input, Button, Alert } from 'antd';
import { SendOutlined, FileWordOutlined } from '@ant-design/icons';
import { useSSAStore } from '../../store/ssaStore';
import { ssaApi } from '../../api/ssaApi';
export const ConsultChat: React.FC = () => {
const [input, setInput] = useState('');
const [loading, setLoading] = useState(false);
const {
sessionId,
messages,
addMessage,
setSession,
setCurrentSAP,
setGeneratingSAP,
isGeneratingSAP
} = useSSAStore();
const handleSend = async () => {
if (!input.trim()) return;
setLoading(true);
// 如果没有会话,先创建
let currentSessionId = sessionId;
if (!currentSessionId) {
const { data } = await ssaApi.createConsultSession();
currentSessionId = data.id;
setSession(data.id, '统计咨询');
}
// 添加用户消息
addMessage({ role: 'user', contentType: 'text', content: { text: input } });
setInput('');
// 发送咨询
const { data } = await ssaApi.consultChat(currentSessionId!, input);
// 添加 AI 回复
addMessage({ role: 'assistant', contentType: 'text', content: { text: data.response } });
setLoading(false);
};
const handleGenerateSAP = async () => {
if (!sessionId) return;
setGeneratingSAP(true);
const { data } = await ssaApi.generateSAP(sessionId);
setCurrentSAP(data);
addMessage({ role: 'assistant', contentType: 'sap', content: data });
setGeneratingSAP(false);
};
return (
<div className="flex flex-col h-full">
{/* 引导提示 */}
<Alert
message="统计咨询模式"
description="描述您的研究设计和分析需求,无需上传数据。完成咨询后可生成统计分析计划(SAP)文档。"
type="info"
showIcon
className="mx-4 mt-4"
/>
{/* 消息流 */}
<div className="flex-1 overflow-auto p-4 space-y-4">
{messages.map(msg => (
<div
key={msg.id}
className={`flex ${msg.role === 'user' ? 'justify-end' : 'justify-start'}`}
>
<div className={`
max-w-[80%] p-3 rounded-lg
${msg.role === 'user'
? 'bg-blue-500 text-white'
: 'bg-slate-100 text-slate-800'}
`}>
{msg.contentType === 'sap'
? <SAPPreview sap={msg.content} />
: msg.content.text
}
</div>
</div>
))}
</div>
{/* 输入区 */}
<div className="p-4 border-t border-slate-200">
<div className="flex gap-2">
<Input.TextArea
value={input}
onChange={(e) => setInput(e.target.value)}
placeholder="描述您的研究设计和统计分析需求..."
autoSize={{ minRows: 2, maxRows: 4 }}
onPressEnter={(e) => {
if (!e.shiftKey) {
e.preventDefault();
handleSend();
}
}}
/>
<div className="flex flex-col gap-2">
<Button
type="primary"
icon={<SendOutlined />}
onClick={handleSend}
loading={loading}
>
</Button>
<Button
icon={<FileWordOutlined />}
onClick={handleGenerateSAP}
loading={isGeneratingSAP}
disabled={messages.length < 2}
>
SAP
</Button>
</div>
</div>
</div>
</div>
);
};
```
### 9.3 SAPPreviewSAP 文档预览)
```tsx
// components/cards/SAPPreview.tsx
import React from 'react';
import { Card, Button, Space, Typography, Divider, Tag } from 'antd';
import { DownloadOutlined, FileWordOutlined, FileMarkdownOutlined } from '@ant-design/icons';
import { ssaApi } from '../../api/ssaApi';
import { useSSAStore } from '../../store/ssaStore';
const { Title, Paragraph, Text } = Typography;
interface SAPDocument {
title: string;
sections: Array<{ heading: string; content: string }>;
recommendedTools: string[];
}
interface SAPPreviewProps {
sap: SAPDocument;
}
export const SAPPreview: React.FC<SAPPreviewProps> = ({ sap }) => {
const { sessionId } = useSSAStore();
const handleDownload = async (format: 'word' | 'markdown') => {
if (!sessionId) return;
const response = await ssaApi.downloadSAP(sessionId, format);
const blob = new Blob([response.data]);
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = format === 'word' ? 'SAP.docx' : 'SAP.md';
a.click();
window.URL.revokeObjectURL(url);
};
return (
<Card
className="sap-preview"
title={
<Space>
<FileWordOutlined className="text-blue-500" />
<span> (SAP)</span>
</Space>
}
extra={
<Space>
<Button
icon={<FileWordOutlined />}
onClick={() => handleDownload('word')}
>
Word
</Button>
<Button
icon={<FileMarkdownOutlined />}
onClick={() => handleDownload('markdown')}
>
Markdown
</Button>
</Space>
}
>
<Title level={4}>{sap.title}</Title>
{sap.sections.map((section, idx) => (
<div key={idx} className="mb-4">
<Title level={5} className="text-slate-700">{section.heading}</Title>
<Paragraph className="text-slate-600">{section.content}</Paragraph>
</div>
))}
<Divider />
<div>
<Text strong></Text>
<div className="mt-2">
{sap.recommendedTools.map((tool, idx) => (
<Tag key={idx} color="blue">{tool}</Tag>
))}
</div>
</div>
</Card>
);
};
```
### 9.4 PlanCard 增强(支持仅下载方案)
```tsx
// components/cards/PlanCard.tsx 增加的按钮
// 在 "确认并执行" 按钮旁边添加:
{/* 🆕 仅下载方案(咨询模式下或用户选择不执行) */}
<Button
icon={<DownloadOutlined />}
onClick={onDownloadPlanOnly}
>
</Button>
```
---

View File

@@ -0,0 +1,318 @@
# SSA 端到端测试与架构讨论
> **日期**: 2026-02-19
> **状态**: ✅ 已决策 - 采用方案 B简化设计仅支持 OSS
> **参与者**: 开发团队
---
## 1. 测试概述
### 1.1 测试目标
验证 SSA 智能统计分析模块的完整数据流:
```
前端 → Node.js 后端 → OSS 存储 → R 统计服务 → 返回结果
```
### 1.2 测试环境
| 组件 | 状态 | 端口 |
|------|------|------|
| Node.js 后端 | ✅ 运行中 | 3001 |
| R Docker 服务 | ✅ 运行中 | 8082 |
| PostgreSQL | ✅ 运行中 | 5432 |
| OSS (开发环境) | ✅ 可用 | ai-clinical-data-dev |
### 1.3 测试脚本
```
backend/tests/ssa-e2e-test.ps1
```
---
## 2. 测试结果
### 2.1 测试步骤与结果
| 步骤 | 描述 | 结果 |
|------|------|------|
| Step 0 | R 服务健康检查 | ✅ 通过 |
| Step 1 | 用户登录认证 | ✅ 通过 |
| Step 2 | SSA 路由检查 | ✅ 通过(路由已注册) |
| Step 3 | 创建分析会话 | ✅ 通过 |
| Step 4 | 上传 CSV 文件 | ✅ 通过(存入 OSS |
| Step 5 | 执行 T 检验 | ❌ 失败(修复前)→ ✅ 通过(修复后) |
### 2.2 发现的问题与修复
#### 问题 1SSA 路由未注册
**现象**: `/api/v1/ssa/*` 返回 404
**原因**: `backend/src/index.ts` 中未注册 SSA 模块路由
**修复**: 添加路由注册
```typescript
// backend/src/index.ts
import { ssaRoutes } from './modules/ssa/index.js';
await fastify.register(ssaRoutes, { prefix: '/api/v1/ssa' });
```
#### 问题 2数据源选择逻辑错误
**现象**: 上传 CSV 后执行分析R 服务报错"列名不存在"
**原因**: `RClientService.buildDataSource()` 优先读取 `session.dataPayload`(为空),返回空数组,忽略了 `session.dataOssKey`
**修复**: 调整优先级,先检查 `dataOssKey`
```typescript
// 修复后的逻辑
private async buildDataSource(session: any) {
// 1. 优先使用 OSS key已上传的文件
if (session.dataOssKey) {
const signedUrl = await storage.getUrl(session.dataOssKey);
return { type: 'oss', oss_url: signedUrl };
}
// 2. 其次使用 inline payload
if (session.dataPayload) {
return { type: 'inline', data: session.dataPayload };
}
// 3. 无数据
return { type: 'inline', data: [] };
}
```
---
## 3. 架构讨论:数据传输设计
### 3.1 当前设计
```
┌─────────────────────────────────────────────────────────────────┐
│ 原设计:混合数据协议(根据大小选择传输方式) │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 数据来源 1: 用户上传文件 → 存入 OSS → dataOssKey │
│ 数据来源 2: 前端传 JSON → 存入内存 → dataPayload │
│ │
│ 执行分析时: │
│ - 有 dataOssKey → 生成预签名 URL → R 服务从 OSS 下载 │
│ - 有 dataPayload 且 < 2MB → 直接传 inline JSON │
│ - 有 dataPayload 且 >= 2MB → 先存 OSS 再传 URL │
│ │
└─────────────────────────────────────────────────────────────────┘
```
### 3.2 实际使用场景分析
| 场景 | 是否存在 | 说明 |
|------|----------|------|
| 用户上传 CSV/Excel 文件 | ✅ **100%** | SSA 核心场景 |
| 前端直接传 JSON 数据 | ❌ **0%** | 产品设计不支持手动输入数据 |
### 3.3 问题:设计与场景不匹配
```
┌─────────────────────────────────────────────────────────────────┐
│ 实际数据流100% 场景) │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 用户 → 上传 CSV → Node.js → 存入 OSS → 记录 dataOssKey │
│ │
│ 执行分析 → 读取 dataOssKey → 生成预签名 URL → R 服务下载 │
│ │
│ dataPayload 永远为空!"判断大小"逻辑从不执行! │
│ │
└─────────────────────────────────────────────────────────────────┘
```
**结论**: 当前代码中的 `dataPayload` 和"根据大小判断"逻辑是**死代码**,永远不会执行。
---
## 4. 待讨论决策
### 4.1 方案 A保持现状保留灵活性
**优点**:
- 未来可能支持"在线输入数据"功能
- 代码改动小
**缺点**:
- 存在永远不执行的代码
- 逻辑复杂度高
- 新开发者可能困惑
### 4.2 方案 B简化设计推荐
```typescript
// 简化后的 buildDataSource
private async buildDataSource(session: any) {
const ossKey = session.dataOssKey;
if (!ossKey) {
throw new Error('请先上传数据文件');
}
const signedUrl = await storage.getUrl(ossKey);
return {
type: 'oss',
oss_url: signedUrl
};
}
```
**优点**:
- 代码简洁
- 逻辑清晰
- 符合实际使用场景
**缺点**:
- 未来如需支持 inline JSON需要重新添加
### 4.3 方案 C完全移除 inline 支持
除了简化 `buildDataSource`,还可以:
- 移除 `ssaSession.dataPayload` 字段
- 移除 R 服务中的 inline JSON 解析逻辑
- 只保留 OSS 数据流
**优点**:
- 最简洁
- 单一数据流,易于维护
**缺点**:
- 改动较大
- 需要修改数据库 schema
---
## 5. 相关文件清单
| 文件 | 作用 |
|------|------|
| `backend/src/modules/ssa/index.ts` | SSA 模块入口 |
| `backend/src/modules/ssa/routes/analysis.routes.ts` | 上传/执行路由 |
| `backend/src/modules/ssa/executor/RClientService.ts` | R 服务调用 |
| `r-statistics-service/utils/data_loader.R` | R 服务数据加载 |
| `backend/tests/ssa-e2e-test.ps1` | 端到端测试脚本 |
---
## 6. 建议结论
1. **短期**: 使用当前修复后的代码,完成 Week 1-2 开发
2. **中期**: 团队讨论后,决定是否采用方案 B 简化设计
3. **长期**: 根据产品需求,确定是否需要支持"在线输入数据"功能
---
## 7. 附录:测试数据
### 测试 CSV 文件
```
r-statistics-service/tests/fixtures/sample_t_test.csv
```
```csv
group,score
A,23
A,25
A,27
A,22
A,24
A,26
A,21
A,28
B,30
B,32
B,28
B,31
B,29
B,33
B,27
B,35
```
### 测试请求参数
```json
{
"plan": {
"tool_code": "ST_T_TEST_IND",
"params": {
"group_var": "group",
"value_var": "score"
},
"guardrails": {
"check_normality": true
}
}
}
```
### 预期结果
```json
{
"status": "success",
"results": {
"method": "Welch Two Sample t-test",
"statistic": -4.78,
"df": 13.90,
"p_value": 0.0003,
"p_value_fmt": "< 0.001"
}
}
```
---
---
## 8. 决策结果
**决策日期**: 2026-02-19
**采用方案**: B - 简化设计,仅支持 OSS
**最终代码**:
```typescript
// backend/src/modules/ssa/executor/RClientService.ts
private async buildDataSource(session: any): Promise<{ type: string; oss_url: string }> {
const ossKey = session.dataOssKey;
if (!ossKey) {
logger.error('[SSA:RClient] No data uploaded', { sessionId: session.id });
throw new Error('请先上传数据文件');
}
logger.info('[SSA:RClient] Building OSS data source', { sessionId: session.id, ossKey });
const signedUrl = await storage.getUrl(ossKey);
return {
type: 'oss',
oss_url: signedUrl
};
}
```
**变更说明**:
- 移除 `dataPayload` 和 inline JSON 支持
- 移除"根据大小判断"逻辑
- 如果未上传文件,直接抛出用户友好错误
- 代码从 30 行简化到 15 行
---
*文档结束。*

View File

@@ -0,0 +1,243 @@
# SSA-Pro 2026-02-19 开发总结
> **版本:** v1.0
> **日期:** 2026-02-19
> **编写:** AI 开发助手
> **状态:** ✅ T 检验端到端测试通过
---
## 1. 开发目标
本日核心目标是**完成 T 检验端到端测试**,并修复测试过程中发现的所有问题。
---
## 2. 完成工作清单
### 2.1 前端模块注册与激活
| 任务 | 状态 | 说明 |
|------|------|------|
| 模块注册 | ✅ 完成 | `moduleRegistry.ts``placeholder: false` |
| 用户会话隔离 | ✅ 修复 | 组件挂载时重置 Zustand store |
| 代码下载文件名 | ✅ 修复 | 从 `Content-Disposition` header 提取真实文件名 |
### 2.2 后端 Bug 修复
| 任务 | 状态 | 说明 |
|------|------|------|
| R 服务错误响应处理 | ✅ 修复 | 检查 `status: error`,返回 422 + `user_hint` |
| 变量智能匹配 | ✅ 修复 | 优先使用用户查询中提到的变量 |
| 代码下载 API | ✅ 增强 | 动态生成文件名:`{toolName}_{dataName}_{MMDD}_{HHmm}.R` |
### 2.3 DataParserService 优化
| 任务 | 状态 | 说明 |
|------|------|------|
| 类型推断优化 | ✅ 完成 | 0/1 数字列识别为分类变量 |
| 规则优先级 | ✅ 完成 | 唯一值 ≤3 或比例 <20% → categorical |
### 2.4 R 服务 Bug 修复
| 任务 | 状态 | 说明 |
|------|------|------|
| 缺失值处理 | ✅ 修复 | 分析前自动过滤 NA/空字符串 |
| 数据清洗日志 | ✅ 新增 | 记录移除的缺失值行数 |
---
## 3. 关键 Bug 修复详情
### 3.1 分组变量识别为 3 组问题
**问题描述:**
- 用户数据 `smoke` 列有值 1、2 和缺失值
- R 服务将缺失值算作第 3 组
- T 检验要求恰好 2 组,返回错误
**修复方案:**
```r
# r-statistics-service/tools/t_test_ind.R
# 数据清洗:移除分组变量或数值变量中的缺失值
df <- df[!is.na(df[[group_var]]) & trimws(as.character(df[[group_var]])) != "", ]
df <- df[!is.na(df[[value_var]]), ]
```
**影响:**
- R 服务自动过滤缺失值
- 日志记录:`数据清洗: 移除 7 行缺失值 (剩余 304 行)`
### 3.2 类型推断错误0/1 列识别为 numeric
**问题描述:**
- `smoke` 列是 0/1 或 1/2 数字
- DataParserService 将其识别为 `numeric` 而非 `categorical`
- 导致变量匹配逻辑找不到分类变量
**修复方案:**
```typescript
// backend/src/modules/ssa/services/DataParserService.ts
// 规则1唯一值很少<=10且比例很低<20%)→ 分类变量
if (uniqueCount <= 10 && uniqueRatio < 0.2) {
return 'categorical';
}
// 规则2即使是数字如果唯一值只有2-3个也视为分类变量
if (uniqueCount <= 3) {
return 'categorical';
}
```
### 3.3 R 服务错误信息未传递给前端
**问题描述:**
- R 服务返回 `status: error``message`
- 后端仍返回 200 OK前端无法显示错误原因
- 用户只看到"执行失败"
**修复方案:**
```typescript
// backend/src/modules/ssa/routes/analysis.routes.ts
if (result?.status === 'error') {
return reply.status(422).send({
status: 'error',
error: result.message || '分析执行失败',
user_hint: result.user_hint || result.message
});
}
```
```typescript
// frontend-v2/src/modules/ssa/hooks/useAnalysis.ts
const errorData = error.response?.data;
const errorMessage = errorData?.user_hint || errorData?.error || '执行出错';
setError(errorMessage);
```
### 3.4 下载代码文件名硬编码
**问题描述:**
- 前端硬编码文件名:`analysis_${sessionId}.R`
- 后端 `Content-Disposition` header 中的动态文件名被忽略
**修复方案:**
```typescript
// frontend-v2/src/modules/ssa/hooks/useAnalysis.ts
const downloadCode = useCallback(async (): Promise<DownloadResult> => {
const response = await apiClient.get(...);
const contentDisposition = response.headers['content-disposition'];
let filename = `analysis_${currentSession.id}.R`;
if (contentDisposition) {
const match = contentDisposition.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/);
if (match) {
filename = decodeURIComponent(match[1].replace(/['"]/g, ''));
}
}
return { blob: response.data, filename };
}, [currentSession]);
```
### 3.5 用户会话隔离问题
**问题描述:**
- 不同用户登录后看到相同的 session 数据
- Zustand store 在页面切换时未重置
**修复方案:**
```tsx
// frontend-v2/src/modules/ssa/index.tsx
useEffect(() => {
reset(); // 组件挂载时重置 store
}, [reset]);
```
---
## 4. 测试验证结果
### 4.1 R 服务直接调用测试
```json
// 请求
POST http://localhost:8082/api/v1/skills/ST_T_TEST_IND
{
"data_source": { "type": "oss", "oss_url": "..." },
"params": { "group_var": "smoke", "value_var": "age" }
}
// 响应
{
"status": "success",
"message": "分析完成",
"results": {
"method": "Welch Two Sample t-test",
"statistic": 0.8812,
"df": 197.5738,
"p_value": 0.3793,
...
},
"plots": ["data:image/png;base64,..."],
"trace_log": [
"数据清洗: 移除 7 行缺失值 (剩余 304 行)",
...
],
"reproducible_code": "# SSA-Pro 自动生成代码..."
}
```
### 4.2 端到端测试流程
| 步骤 | 状态 | 说明 |
|------|------|------|
| 1. 上传数据 | ✅ 通过 | CSV 文件上传到 OSS |
| 2. 数据解析 | ✅ 通过 | Schema 正确识别变量类型 |
| 3. 生成计划 | ✅ 通过 | 正确匹配 smoke(分类) + age(数值) |
| 4. 执行分析 | ✅ 通过 | R 服务返回完整结果 |
| 5. 结果展示 | ✅ 通过 | 统计结果 + 图表 + 代码 |
| 6. 代码下载 | ✅ 通过 | 动态文件名生效 |
---
## 5. 代码变更清单
| 文件 | 变更类型 | 说明 |
|------|----------|------|
| `r-statistics-service/tools/t_test_ind.R` | 增强 | 缺失值自动过滤 |
| `backend/src/modules/ssa/services/DataParserService.ts` | 增强 | 类型推断优化 |
| `backend/src/modules/ssa/routes/analysis.routes.ts` | 修复 | R 错误响应处理 + 动态文件名 |
| `frontend-v2/src/modules/ssa/hooks/useAnalysis.ts` | 修复 | 错误信息提取 + 文件名获取 |
| `frontend-v2/src/modules/ssa/index.tsx` | 修复 | 用户会话隔离 |
| `frontend-v2/src/framework/modules/moduleRegistry.ts` | 更新 | 激活 SSA 模块 |
---
## 6. MVP 进度更新
| Phase | 任务数 | 已完成 | 进度 |
|-------|--------|--------|------|
| Phase 1 | 49 | 38 | 78% |
| Phase 2 | 31 | 0 | 0% |
| Phase 3 | 26 | 0 | 0% |
| **总计** | **106** | **38** | **36%** |
---
## 7. 遗留问题与后续工作
### 7.1 待完成任务Phase 1
| 任务 | 优先级 | 说明 |
|------|--------|------|
| 配置中台DecisionTableLoader | 中 | 四维匹配逻辑 |
| 配置中台RCodeLibraryService | 中 | 脚本上传/版本管理 |
| DataParserService 隐私保护 | 低 | 稀有值 < 5 隐藏 |
| 安装 json-repair + zod | 低 | LLM 输出容错 |
### 7.2 下一步计划
1. **进入 Phase 2** - 实现更多统计方法ANOVA、卡方检验等
2. **或完善 Phase 1** - 配置中台基础功能
---
**2026-02-19 开发总结完成。**

View File

@@ -0,0 +1,98 @@
# **SSA-Pro R 服务代码深度审查报告**
**审查对象:** SSA-Pro R Service Source Code (v1.0)
**审查文件:** Dockerfile, plumber.R, data\_loader.R, guardrails.R, etc.
**审查时间:** 2026-02-18
**审查结论:** 🟡 **总体优秀,但存在阻断性缺失 (Blocker)**
## **1\. 🚨 阻断性问题 (Critical Issues)**
**这些问题会导致服务无法启动或无法下载数据,必须在联调前修复。**
### **1.1 data\_loader.R 中缺失 OSS 签名函数**
* **问题描述**:在 data\_loader.R 第 63 行调用了 generate\_oss\_signature(config, "GET", oss\_key),但我翻遍了上传的所有文件,**没有找到这个函数的定义**。
* **风险**:代码运行到下载 OSS 步骤时会直接报错 Error: could not find function "generate\_oss\_signature"。
* **修复建议**
1. **方案 A (推荐)**:在 utils/ 下新建 oss\_signer.R实现阿里云 OSS 的 HMAC-SHA1 签名逻辑(需要引入 digest 和 base64enc 包)。
2. **方案 B (替代)**:如果不想手写签名,可以使用系统调用 awscli (配置阿里云 endpoint) 或寻找现成的 R 包(如 aliyunr但需验证维护状态
### **1.2 plumber.R 的动态加载性能隐患**
* **问题描述**:在 plumber.R 的 POST /api/v1/skills/\<tool\_code\> 接口中,第 38 行使用了 source(tool\_file)。这意味着**每次请求都会重新从磁盘读取并解析 R 脚本**。
* **风险**
* **开发环境**:这是好事,支持热重载。
* **生产环境**:这是性能杀手。在高并发下,频繁的磁盘 I/O 和语法解析会显著增加延迟。
* **修复建议**
* 引入 DEV\_MODE 变量判断。
* **生产环境**:在服务启动时(第 13 行左右)预先加载所有 tools/ 下的脚本,或者使用 environment 缓存已加载的函数。
* **开发环境**:保持现有的动态 source 逻辑。
## **2\. 工程与安全隐患 (Engineering & Security Risks)**
### **2.1 Docker 容器的 Root 权限风险**
* **问题描述**Dockerfile 未指定用户,默认使用 root 运行 R 服务。
* **风险**:如果 R 代码中存在漏洞(如允许执行系统命令 system()),攻击者将获得容器的 Root 权限,可能逃逸或破坏文件系统。
* **修复建议**:在 Dockerfile 末尾添加非特权用户切换:
RUN useradd \-m appuser
USER appuser
### **2.2 路径遍历攻击 (Path Traversal)**
* **问题描述**plumber.R 第 33 行:
tool\_file \<- file.path("tools", paste0(tolower(gsub("ST\_", "", tool\_code)), ".R"))
虽然做了 gsub但如果 tool\_code 包含 ../ 等字符,仍可能尝试访问上层目录。
* **修复建议**:增加严格的白名单校验,或者校验 tool\_code 只能包含字母、数字和下划线。
if (\!grepl("^\[A-Z0-9\_\]+$", tool\_code)) {
return(list(status="error", message="Invalid tool code format"))
}
## **3\. 最佳实践点赞 (Highlights) ✅**
1. **依赖锁定 (renv.lock)**:使用了 renv 进行包管理,这是 R 工程化的基石,做得非常棒。
2. **护栏设计 (guardrails.R)**
* 包含了 LARGE\_SAMPLE\_THRESHOLD (5000) 的抽样逻辑,避免了大样本下 Shapiro 检验过敏的问题,非常专业的统计学处理。
* 接口设计清晰 (passed, action, reason)。
3. **结果格式化 (result\_formatter.R)**:统一处理了 P 值 \< 0.001 的显示,符合 APA 规范。
4. **环境隔离 (docker-compose.yml)**:正确使用了环境变量注入 OSS 配置,且区分了开发/生产环境。
## **4\. 优化代码清单 (Code Improvement Snippets)**
### **补全 OSS 签名逻辑 (utils/oss\_signer.R)**
*这部分逻辑比较复杂,我直接提供一个简版实现供参考:*
library(digest)
library(base64enc)
generate\_oss\_signature \<- function(config, verb, resource) {
date \<- format(Sys.time(), "%a, %d %b %Y %H:%M:%S GMT", tz="GMT")
content\_type \<- ""
content\_md5 \<- ""
canonicalized\_resource \<- paste0("/", config$bucket, "/", resource)
string\_to\_sign \<- paste(verb, content\_md5, content\_type, date, "", canonicalized\_resource, sep="\\n")
signature \<- base64encode(hmac(config$access\_key\_secret, string\_to\_sign, algo="sha1", raw=TRUE))
auth\_header \<- paste0("OSS ", config$access\_key\_id, ":", signature)
return(c("Authorization" \= auth\_header, "Date" \= date))
}
*注意:需要在 renv.lock 中补充 digest 包。*
## **5\. 总结**
这份代码作为 MVP 已经达到了 **85分** 的水平。
**接下来的行动指南:**
1. **必须做**:补全 generate\_oss\_signature 函数(或相关文件)。
2. **必须做**:在 renv 中添加 digest 依赖。
3. **建议做**:优化 plumber.R 的生产环境加载逻辑。
请将这份报告发给 R 开发工程师,让他们快速修正,然后就可以开始构建镜像了。

View File

@@ -0,0 +1,260 @@
# SSA-Pro 模块 Week 1 开发总结报告
> **版本:** v1.0
> **日期:** 2026-02-19
> **编写:** AI 开发助手
> **状态:** ✅ Week 1 完成
---
## 📋 目录
1. [开发目标](#1-开发目标)
2. [完成工作清单](#2-完成工作清单)
3. [关键决策与讨论](#3-关键决策与讨论)
4. [技术挑战与解决方案](#4-技术挑战与解决方案)
5. [代码审查与规范对齐](#5-代码审查与规范对齐)
6. [产出物清单](#6-产出物清单)
7. [遗留问题与后续工作](#7-遗留问题与后续工作)
---
## 1. 开发目标
Week 1 的核心目标是**搭建 SSA-Pro 模块的技术骨架**,包括:
- R 统计服务 Docker 环境
- 后端 SSA 模块结构
- 前端 SSA 模块结构
- 数据库 Schema 设计
---
## 2. 完成工作清单
### 2.1 R 统计服务 (r-statistics-service)
| 任务 | 状态 | 说明 |
|------|------|------|
| Dockerfile 编写 | ✅ 完成 | 基于 `rocker/r-ver:4.3`,包含完整系统依赖 |
| plumber.R API 入口 | ✅ 完成 | 健康检查、工具列表、技能执行 |
| data_loader.R | ✅ 完成 | 支持 inline 数据和预签名 URL |
| guardrails.R | ✅ 完成 | 正态性、方差齐性、样本量检验 |
| error_codes.R | ✅ 完成 | 友好错误映射 |
| result_formatter.R | ✅ 完成 | APA 格式化 |
| t_test_ind.R 示例工具 | ✅ 完成 | 独立样本 T 检验 |
| Docker 镜像构建 | ✅ 完成 | `ssa-r-statistics:1.0.1`1.81GB |
### 2.2 后端模块 (backend/src/modules/ssa)
| 任务 | 状态 | 说明 |
|------|------|------|
| 模块目录结构 | ✅ 完成 | 标准模块结构 |
| index.ts 入口 | ✅ 完成 | 使用 `authenticate` 中间件 |
| session.routes.ts | ✅ 完成 | 会话管理 API |
| analysis.routes.ts | ✅ 完成 | 分析执行 APIOSS 存储集成 |
| consult.routes.ts | ✅ 完成 | 咨询模式 APILLM 网关集成 |
| config.routes.ts | ✅ 完成 | 配置管理 API |
| RClientService.ts | ✅ 完成 | R 服务客户端,预签名 URL 支持 |
### 2.3 前端模块 (frontend-v2/src/modules/ssa)
| 任务 | 状态 | 说明 |
|------|------|------|
| 模块目录结构 | ✅ 完成 | 标准模块结构 |
| index.tsx 入口 | ✅ 完成 | 主布局组件 |
| useAnalysis.ts Hook | ✅ 完成 | 使用 apiClient 认证 |
| 组件骨架 | ✅ 完成 | DataUploader, PlanConfirm 等 |
### 2.4 数据库 Schema
| 任务 | 状态 | 说明 |
|------|------|------|
| Prisma Schema 定义 | ✅ 完成 | 9 个 SSA 相关模型 |
| Migration SQL | ✅ 完成 | 手动创建并应用 |
---
## 3. 关键决策与讨论
### 3.1 OSS 访问方案
**讨论背景:**
- 开发团队审查报告建议 R 服务实现 OSS 签名(`oss_signer.R`
- 这需要 R 服务持有 OSS 密钥
**最终决策:** ❌ 不采用 R 直接签名方案
**采用方案:** 预签名 URL
```
Node.js 生成预签名 URL → 传递给 R 服务 → R 直接 GET 下载
```
**理由:**
1. 符合平台 OSS 存储规范(密钥集中管控)
2. R 服务无需持有敏感密钥
3. 简化 R 代码复杂度
### 3.2 生产环境性能优化
**问题:** `plumber.R` 每次请求都 `source()` 工具脚本
**解决方案:**
```r
# 生产环境:启动时预加载到 TOOL_CACHE
if (!DEV_MODE) {
preload_tools() # 缓存 run_analysis 函数
}
```
### 3.3 安全加固
| 问题 | 解决方案 |
|------|----------|
| Docker Root 权限 | 添加 `USER appuser` |
| 路径遍历攻击 | `tool_code` 正则白名单 `^[A-Z][A-Z0-9_]*$` |
---
## 4. 技术挑战与解决方案
### 4.1 Prisma Migration Drift
**问题:** `prisma migrate dev` 检测到 drift要求 `migrate reset`
**解决方案:**
1. 手动创建 SQL 文件
2. 直接执行 SQL
3. 使用 `prisma migrate resolve --applied` 标记已应用
### 4.2 Docker 构建依赖问题
**问题链:**
```
zlib.h 缺失 → httpuv 编译失败
cmake 缺失 → nloptr 编译失败
ggplot2 版本冲突 → cowplot 安装失败
```
**解决方案:**
1. 添加系统依赖:`zlib1g-dev`, `cmake`, `libnlopt-dev`, `gfortran`
2. 放弃 renv直接 `install.packages()` 让 R 自动解决依赖
### 4.3 PowerShell 重定向问题
**问题:** `<` 操作符在 PowerShell 中被保留
**解决方案:**
```powershell
Get-Content "file.sql" | docker exec -i postgres psql ...
```
---
## 5. 代码审查与规范对齐
Week 1 后期进行了一次重要的**规范对齐审查**,确保新代码遵循平台规范。
### 5.1 发现的问题
| 文件 | 问题 | 修复 |
|------|------|------|
| `useAnalysis.ts` | 使用原生 fetch无认证 | 改用 `apiClient` |
| `ssa/index.ts` | 自定义 authenticate | 使用平台 `authenticate` 中间件 |
| `RClientService.ts` | 直接传 OSS key | 使用 `storage.getUrl()` 预签名 |
| `ConsultChat.tsx` | 自定义 Chat 组件 | 删除,使用平台 `AIStreamChat` |
| 各 routes | 手动获取 userId | 使用 `getUserId(request)` |
### 5.2 参考规范文档
- `docs/02-通用能力层/00-通用能力层清单.md`
- `docs/04-开发规范/10-模块认证规范.md`
- `docs/04-开发规范/11-OSS存储开发规范.md`
---
## 6. 产出物清单
### 6.1 代码文件
```
r-statistics-service/
├── Dockerfile # 生产就绪
├── docker-compose.yml # 本地开发
├── plumber.R # API 入口
├── utils/
│ ├── data_loader.R # 预签名 URL 方案
│ ├── guardrails.R # Block/Warn/Switch
│ ├── error_codes.R
│ └── result_formatter.R
├── tools/
│ └── t_test_ind.R # 示例工具
└── tests/fixtures/
└── normal_data.csv
backend/src/modules/ssa/
├── index.ts
├── routes/
│ ├── session.routes.ts
│ ├── analysis.routes.ts
│ ├── consult.routes.ts
│ └── config.routes.ts
├── executor/
│ └── RClientService.ts
└── types/
frontend-v2/src/modules/ssa/
├── index.tsx
├── components/
├── hooks/
│ └── useAnalysis.ts
└── types/
```
### 6.2 Docker 镜像
| 镜像名 | 版本 | 大小 | 状态 |
|--------|------|------|------|
| `ssa-r-statistics` | 1.0.1 | 1.81 GB | ✅ 本地构建成功 |
### 6.3 数据库 Schema
- `ssa_schema` 命名空间
- 9 个新表:`SsaSession`, `SsaMessage`, `SsaTool`, `SsaExecutionLog`
---
## 7. 遗留问题与后续工作
### 7.1 待完成任务
| 任务 | 优先级 | 说明 |
|------|--------|------|
| 后端主路由注册 | P0 | 将 SSA 路由加入 `index.ts` |
| 前端模块注册 | P0 | 加入 `moduleRegistry.ts` |
| T 检验数据格式调试 | P1 | JSON 转 data.frame 格式问题 |
| 配置中心 Excel 模板 | P1 | 决策表、参数映射等 |
### 7.2 Week 2 计划
1. **完成模块注册** - 后端/前端路由注册
2. **端到端测试** - 数据上传 → 计划生成 → 执行
3. **配置中心实现** - DecisionTableLoader, RCodeLibraryService
4. **Planner 引擎** - LLM 方法推荐逻辑
---
## 附录:关键文件变更记录
| 文件 | 变更类型 | 变更内容 |
|------|----------|----------|
| `data_loader.R` | 重构 | OSS 签名 → 预签名 URL |
| `plumber.R` | 增强 | 生产预加载 + tool_code 校验 |
| `Dockerfile` | 增强 | 非特权用户 + 健康检查 |
| `RClientService.ts` | 修复 | 使用 storage.getUrl() |
| `useAnalysis.ts` | 修复 | 使用 apiClient |
| `ssa/index.ts` | 修复 | 使用平台 authenticate |
---
**Week 1 开发总结完成。**

View File

@@ -0,0 +1,56 @@
# utils/oss_signer.R
# 阿里云 OSS 签名生成器 (R语言实现)
# 参考文档: https://help.aliyun.com/document_detail/31951.html
library(digest)
library(base64enc)
#' 生成 OSS API 签名头
#' @param config 包含 access_key_id, access_key_secret, bucket 的列表
#' @param verb HTTP 方法 (GET, PUT, etc.)
#' @param resource OSS 资源路径 (例如 "/my-bucket/data/file.csv")
#' @param content_type 内容类型 (可选)
#' @param content_md5 内容 MD5 (可选)
#' @return 包含 Authorization 和 Date 的命名向量
generate_oss_signature <- function(config, verb, resource, content_type = "", content_md5 = "") {
# 1. 生成标准时间戳 (GMT 格式)
# 例如: "Thu, 18 Feb 2026 08:00:00 GMT"
date <- format(Sys.time(), "%a, %d %b %Y %H:%M:%S GMT", tz="GMT")
# 2. 构造 CanonicalizedResource
# 格式: /BucketName/ObjectName
canonicalized_resource <- paste0("/", config$bucket, "/", resource)
# 3. 构造 StringToSign
# 格式:
# VERB + "\n" +
# Content-MD5 + "\n" +
# Content-Type + "\n" +
# Date + "\n" +
# CanonicalizedOSSHeaders +
# CanonicalizedResource
# 注意: 这里简化处理,未包含 CanonicalizedOSSHeaders (x-oss-*)
string_to_sign <- paste(
verb,
content_md5,
content_type,
date,
canonicalized_resource,
sep = "\n"
)
# 4. 计算 HMAC-SHA1 签名
# 使用 AccessKeySecret 作为密钥
signature <- base64encode(hmac(config$access_key_secret, string_to_sign, algo = "sha1", raw = TRUE))
# 5. 构造 Authorization 头
auth_header <- paste0("OSS ", config$access_key_id, ":", signature)
# 返回需要的 Headers
return(c(
"Authorization" = auth_header,
"Date" = date
))
}

View File

@@ -0,0 +1,255 @@
15810435207
18010009162
15010181209
15611963795
18611348738
13943635313
13581727231
13810478176
13410168373
13811282647
17801082043
15605519676
18919636592
18756032620
13866173932
13522189226
18365256560
15221056490
13803774813
13956060845
18909696293
18601278833
13911933105
13810366704
13675628031
17356719361
15910681644
19909678258
13696540086
13051291428
13681000859
13910110950
18611103631
13683036620
15570146357
18210079257
18920525052
18611685198
19350528610
13611720680
15101021070
18560082439
17801014125
15801430103
15501120199
13683016715
15501007199
13241516357
13466759883
13911680467
15552835306
13049169421
谢一泓
15010497945
13552951189
18810957336
13717936224
13220461848
18600017812
13611209306
13811794835
15911086290
18612835027
13301336613
13391567801
13912635742
15882051125
18280063640
aaa
18611111111
18622222222
18633333333
18644444444
13718974561
15201593792
15501026871
17860691820
15652526290
18800104320
15235537621
15117925628
18954156864
18610085697
15201278137
15201647621
13810483563
18502894620
15822165166
18852010317
13552405525
15010891570
13811459968
13439020885
13811111111
13269893936
15510992666
13520658969
13366288066
18701021830
15210513935
13816919105
13761189664
15175115755
15022188250
17331514756
17625924413
13122859786
18663667466
18801081160
18811723822
13810384929
13001231836
16710815063
15611908852
18522085055
13693638871
15210325676
13611111111
13622222222
冀召帅
18310402093
18610164730
13810944609
13720413071
13826610404
18219857717
15698937284
15998659426
18710675876
17628489151
17602871544
17877005510
15123612362
18098875654
15029098264
18047668006
18219029950
17387997553
13571875487
18715854003
18970132004
18686782201
18545662842
18734121203
13899313719
18779835021
13751562435
15779163306
18900913095
15129745755
13560521592
13810002741
15032631293
15838062093
10001000127
18610000128
13520004917
18222376451
13752570372
13581787350
18600589965
13901009038
18759221287
18560080524
13611728840
15120022447
15358136676
15920493789
18900918397
13467609491
15924177038
18758096745
18845764494
18340809532
18800161511
17721871290
15951987578
13361656372
17734891246
17637350926
18037763215
18180230754
18600161380
18701658727
13522421109
18621015623
17329403301
13811401686
13818015615
13810137047
13810947856
13581878417
18618269437
13011825605
13522757239
13811280948
15611908668
18511650863
15699911299
13911598100
13810964766
13811490288
18610966092
13681324810
17737311521
19834513308
15188376900
15803820068
15306419073
15237360867
15237125268
15039063646
13001253689
13581663887
18268383011
13161658808
15120011793
19959113334
15810853270
15081212977
18810793312
13811113460
13691081209
15801391489
15611063099
15010079214
13366972832
13911315318
13683657545
13811502555
15210610941
13911063662
18810834462
15601212632
13811286188
18610381719
13699201941
13683349097
13911857210
15101120796
13641099415
13601060345
18811728779
15901241029
13381177395
18910938225
13910667213
13611218802
13910785151
18611286922
13121909939
15010115375
18810670329
13693160086
13810281260

View File

@@ -0,0 +1,230 @@
手机号,姓名,医院,部门
13621369297,刘佳兴,北京大学第三医院,病案科
13552371972,张丹,北京大学第三医院,病案科
13439604857,刘青青,北京大学第三医院,病案科
15910968332,李安临,北京大学第三医院,病案科
15901081908,高源,北京大学第三医院,病案科
15011401691,李婧楠,北京大学第三医院,病案科
13466326635,李杨,北京大学第三医院,病案科
13641084052,詹思延,北京大学第三医院,临床流行病学研究中心
13651044855,张洁,北京大学第三医院,生物样本库
15611963681,穆荣,北京大学第三医院,风湿免疫科
18810106285,张现化,北京大学第三医院,药学部
18911482830,徐懋,北京大学第三医院,麻醉科
13811289616,金姬延,北京大学第三医院,骨科
18611302030,张坤,北京大学第三医院,妇科
15811123680,邓秀文,北京大学第三医院,肿瘤放疗科
15611963578,关里,北京大学第三医院,职业病科
15810866570,夏宇曦,北京大学第三医院,医务处
13810627171,张迎宏,北京大学第三医院,耳鼻喉
15810394568,陈芷谦,北京大学第三医院,老年病内科
13810517083,柯嘉,北京大学第三医院,耳鼻喉科
13488693118,郝燕婷,北京大学第三医院,老年科
18514507016,朱薇,北京大学第三医院,疼痛科
13910979132,孙永昌,北京大学第三医院,呼吸内科
13521696306,杜俊,北京大学第三医院,医院感染管理处
18510967299,方英伦,北京大学第三医院,麻醉科
15210502975,雷润宏,北京大学第三医院,放疗科
13683363301,林玉晶,北京大学第三医院,老年内科
15210907141,刘佳,北京大学第三医院,老年内科
13521661293,曲昂,北京大学第三医院,肿瘤放疗科
18701567019,李潇潇,北京大学第三医院,药学部
13810001444,张晓盈,北京大学第三医院,风湿免疫科
15600561969,门鹏,北京大学第三医院,药学部
13810388916,杨诗源,北京大学第三医院,超声医学科
18839790793,李菲,北京大学第三医院,内分泌科
13261875609,宫萍,北京大学第三医院,老年病内科
13120336070,么雪婷,北京大学第三医院,药物临床试验机构
15201113598,魏枢华,北京大学第三医院,肿瘤放疗科
13370137181,李云峰,北京大学第三医院,伤口治疗中心
15010341566,王安琪,北京大学第三医院,皮肤科
15801376598,王蕊,北京大学第三医院,护理部
13522503401,武大伟,北京大学第三医院,耳鼻喉科
15652387205,王淑慧,北京大学第三医院,药剂科
13321185611,杨丽,北京大学第三医院,药剂科
15910965193,王丽嫄,北京大学第三医院,药剂科
18810533012,武慧,北京大学第三医院,儿科
15611272855,吴捷颖,北京大学第三医院,神经内科
13811111694,郭福新,北京大学第三医院,肿瘤放疗科
18842627633,刘爽,北京大学第三医院,药学部
13041210677,张龙,北京大学第三医院,伤口治疗中心
15611908587,苏春燕,北京大学第三医院,肾内科
15110158268,胡娴静,北京大学第三医院,护理部
18611692313,陈领,北京大学第三医院,伤口治疗中心
15010395820,李烜,北京大学第三医院,伤口治疗中心
13699176380,王璟,北京大学第三医院,肿瘤化疗与放射病科
13141078611,郑伟,北京大学第三医院,神经内科
15273111073,许佳琪,北京大学第三医院,普通外科
18519650377,张晓静,北京大学第三医院,门诊部
15210716367,王艺萌,北京大学第三医院,皮肤科
15810292912,胡明奥,北京大学第三医院,骨科
18210293651,王晶玭,北京大学第三医院,护理部
17812003135,孙文凡,北京大学第三医院,机场住院管理中心
13910989410,赵荣生,北京大学第三医院,药学部
15010676497,董佳蕙,北京大学第三医院,药学部
18811358039,安宇婷,北京大学第三医院,神经外科
18310836575,刘泽强,北京大学第三医院,检验科
13717959904,周玉洁,北京大学第三医院,普外科
13522391517,赵东芳,北京大学第三医院,全科医学科
13521115717,郭金竹,北京大学第三医院,皮肤科
17837013925,马文静,北京大学第三医院,产科三病房
13264046126,荆天意,北京大学第三医院,妇产科
15611963829,邓绍晖,北京大学第三医院,泌尿外科
13501301199,张艳平,北京大学第三医院,骨科
19800308903,王梦瑞,北京大学第三医院,麻醉科
15210099011,马莉,北京大学第三医院,急诊科
13552930403,强光亮,北京大学第三医院,胸外科
13051581652,马善吴,北京大学第三医院,胸外科
18511756295,陈凤发,北京大学第三医院,胸外科
13651253466,贺未,北京大学第三医院,胸外科
13681397086,李桂芬,北京大学第三医院,急诊
13810644825,汪宇鹏,北京大学第三医院,心血管内科
13811081300,刘文静,北京大学第三医院,感染疾病科
13522517275,张玉洁,北京大学第三医院,妇产科
17611059621,张晓琦,北京大学第三医院,机场发热急诊
18510993486,姜雅楠,北京大学第三医院,儿科
13466552713,马媛,北京大学第三医院,心血管内科
13520953609,汪宗昱,北京大学第三医院,危重医学科
18601309265,闫辉,北京大学第三医院,运动医学
15901129743,王晓毅,北京大学第三医院,老年内科
18600122874,苗欣,北京大学第三医院,运动医学科
17309573451,张辉,北京大学第三医院,感染疾病科
15811221023,刘维,北京大学第三医院,药学部
18810535187,刘聪颖,北京大学第三医院,心血管内科
18810793282,谢鹏昕,北京大学第三医院,心内科
15801509989,任佳梦,北京大学第三医院,心内科
15026613596,姜熙平,北京大学第三医院,运动医学科
15010388257,郑康,北京大学第三医院,急诊科
13716250148,谭鲁平,北京大学第三医院,感染疾病科
13701366871,焦晨,北京大学第三医院,运动医学
17812091912,何华钰,北京大学第三医院,胸外科
13811232349,叶剑飞,北京大学第三医院,泌尿外科
15611908285,侯小飞,北京大学第三医院,泌尿外科
13581517190,宋一萌,北京大学第三医院,泌尿
18800198507,张展奕,北京大学第三医院,泌尿外科
13810619450,张树栋,北京大学第三医院,泌尿外科
13601280387,魏瑗,北京大学第三医院,产科
13601375861,王墨培,北京大学第三医院,肿瘤化疗与放射病科
13910093201,王欣,北京大学第三医院,眼科
13683587263,鲁胜楠,北京大学第三医院,运动医学科
15811169856,修萌,北京大学第三医院,肿瘤化疗与放射病科
15611908421,王璐,北京大学第三医院,泌尿
15810945282,容晓莹,北京大学第三医院,麻醉科
13811958963,易福梅,北京大学第三医院,肿瘤化疗与放射病科
17778024393,熊振成,北京大学第三医院,胸外科
18618451603,宁英泽,北京大学第三医院,胸外科
15652930253,林楚童,北京大学第三医院,胸外科
19800308315,张秩荻,北京大学第三医院,耳鼻喉科
15210197219,严超,北京大学第三医院,耳鼻喉
13901193611,杨楠,北京大学第三医院,输血科
13520272493,贾博奇,北京大学第三医院,医学工程处
15001393084,李倩,北京大学第三医院,肿瘤化疗与放射病科
13683207954,皮彦斌,北京大学第三医院,运动医学科
13521135624,乔红梅,北京大学第三医院,呼吸科
13810944609,王旖旆,北京大学第三医院,医院管理研究所/医务处互联网医院
13366621285,乐云逸,北京大学第三医院,内分泌
13716382577,杨纨,北京大学第三医院,生殖中心
18811199268,解紫钧,北京大学第三医院,眼科
13146119710,王凯,北京大学第三医院,呼吸二病房
13641391234,张雁林,北京大学第三医院,职业病科
13801018940,赵传多,北京大学第三医院,胸外科
13810369383,朱明珂,北京大学第三医院,呼吸与危重症医学科
15534245986,高旭,北京大学第三医院,感染疾病科
18611103019,陈立雪,北京大学第三医院,生殖中心
13366448899,庞新亚,北京大学第三医院,胸外科
13522535950,汪大伟,北京大学第三医院,人事处
18210066530,吴悦,北京大学第三医院,运动医学
13466734131,李小涵,北京大学第三医院,机场住院管理中心
18627743603,王苏蒙,北京大学第三医院,门诊部
18811771533,郭晨霞,北京大学第三医院,呼吸与危重医学科
13811854669,刘敬,北京大学第三医院,眼科
13616555411,潘佳飞,北京大学第三医院,运动医学科
18811097321,赵赞梅,北京大学第三医院,职业病科
15001341733,张丛溪,北京大学第三医院,呼吸科
13466681757,徐东晓,北京大学第三医院,心内科
18612209826,索玲格,北京大学第三医院,眼科
18613891959,王蒙,北京大学第三医院,呼吸科
13651315864,杨琨,北京大学第三医院,内分泌科
13810700702,耿轩,北京大学第三医院,感染疾病科
18600640125,申展,北京大学第三医院,眼科
13811934661,汪恒,北京大学第三医院,教育处
13681384037,张文慧,北京大学第三医院,内分泌科
16601101165,王媛媛,北京大学第三医院,妇产科
13810970463,何明燕,北京大学第三医院,眼科
18518079113,耿春静,北京大学第三医院,麻醉科
18810598535,吴天晨,北京大学第三医院,妇产科
18210815929,王佳韵,北京大学第三医院,心内科
13641088743,徐欣月,北京大学第三医院,心血管内科
18511712197,王郝霖霖,北京大学第三医院,心血管内科
13910248978,董玥,北京大学第三医院,心内科
13683325888,贾珊,北京大学第三医院,医疗美容科
13050775099,吴奕璇,北京大学第三医院,生殖中心
15001245084,金司爻,北京大学第三医院,药学部
13439199415,张莹,北京大学第三医院,疾病预防控制处
18710002823,吉喆,北京大学第三医院,肿瘤放疗科
18811569934,陈广辉,北京大学第三医院,骨科
15501117899,邢珍珍,北京大学第三医院,职业病科
15010299379,隋鑫宇,北京大学第三医院,心血管内科
18210500535,杨振锟,北京大学第三医院,口腔科
13651309071,秦京京,北京大学第三医院,全科
13121969380,王松,北京大学第三医院,肾内科
18811602096,韩悦,北京大学第三医院,全科医学科
13910149228,杨振华,北京大学第三医院,全科医学科
13146521125,田金金,北京大学第三医院,体检中心
15101597802,王秀会,北京大学第三医院,健康医学科
17812168102,宋一帆,北京大学第三医院,全科
15117919257,刘珊,北京大学第三医院,健康医学科
18701003211,张涛涛,北京大学第三医院,体检中心
15652930820,孙晓燕,北京大学第三医院,呼吸
19801109952,李彤昕,北京大学第三医院,全科医学科
18813037896,李丹,北京大学第三医院,全科医学科
18310189257,王晶,北京大学第三医院,心血管内科
18610218375,孟亚男,北京大学第三医院,呼吸内科一病房
13911533466,张浩琳,北京大学第三医院,中医科
13521181273,张星雨,北京大学第三医院,心血管内科
13810002686,田勍,北京大学第三医院,内分泌
15101021070,魏蕊,北京大学第三医院,内分泌
15201303542,姚艳红,北京大学第三医院,肿瘤化疗科
13366373225,刘爱华,北京大学第三医院,内分泌科
13141213609,马兰,北京大学第三医院,血液科
18811771268,汪羚利,北京大学第三医院,血液科
13651391951,王闻博,北京大学第三医院,内分泌科
13810349928,杨硕,北京大学第三医院,生殖医学科
13381281669,闫燕,北京大学第三医院,耳鼻喉
13513235782,王悦,北京大学第三医院,内分泌
18810887828,张少存,北京大学第三医院,风湿免疫科
13126863268,王琛,北京大学第三医院,风湿免疫科
13396234497,郭苇,北京大学第三医院,风湿免疫科
18600213506,王月麟,北京大学第三医院,眼科
18911576658,翟佳羽,北京大学第三医院,风湿免疫科
18610121529,王钰,北京大学第三医院,妇科
18610121529,王钰,北京大学第三医院,妇科
13426248158,周庆涛,北京大学第三医院,呼吸内科
15201304342,刘绍清,北京大学第三医院,口腔科
13269309414,田小蒙,北京大学第三医院,生殖中心
18600017812,赵威,北京大学第三医院,心血管内科、全科医学科
13466393220,武睿,北京大学第三医院,病理科
13701010401,贺慧颖,北京大学第三医院,病理科
15810390491,姚瑶,北京大学第三医院,病理科
18801235695,李丹阳,北京大学第三医院,病理科
18754278830,季惠惠,北京大学第三医院,病理科
13810648499,郑丹枫,北京大学第三医院,病理科
13683697009,梅放,北京大学第三医院,病理科
13488692897,王惠,北京大学第三医院,病理科
15626042244,宋子秀,北京大学第三医院,病理科
13651215671,刘从容,北京大学第三医院,病理
13269029317,裴斐,北京大学第三医院,病理科
18811331969,王玮,北京大学第三医院,病理科
15611908149,刘岩,北京大学第三医院,病理科
13801211548,杨菁,北京大学第三医院,病理科
15210025586,刘士榕,北京大学第三医院,超声医学科
13601197736,张雪莹,北京大学第三医院,人事处
18610883971,应华,北京大学第三医院,感染疾病科
18610883971,应华,北京大学第三医院,感染疾病科
18610377492,刘蕊,北京大学第三医院,风湿免疫科
18810533283,胡阿锦,北京大学第三医院,病理科
13910627163,崔立刚,北京大学第三医院,超声医学科
13810920592,高皓宇,北京大学第三医院,医院感染管理处
15652249516,白易,北京大学第三医院,医院感染管理处
13581530835,王少利,北京大学第三医院,医院感染管理处
13681085393,冯香凝,北京大学第三医院,采购管理中心
1 手机号 姓名 医院 部门
2 13621369297 刘佳兴 北京大学第三医院 病案科
3 13552371972 张丹 北京大学第三医院 病案科
4 13439604857 刘青青 北京大学第三医院 病案科
5 15910968332 李安临 北京大学第三医院 病案科
6 15901081908 高源 北京大学第三医院 病案科
7 15011401691 李婧楠 北京大学第三医院 病案科
8 13466326635 李杨 北京大学第三医院 病案科
9 13641084052 詹思延 北京大学第三医院 临床流行病学研究中心
10 13651044855 张洁 北京大学第三医院 生物样本库
11 15611963681 穆荣 北京大学第三医院 风湿免疫科
12 18810106285 张现化 北京大学第三医院 药学部
13 18911482830 徐懋 北京大学第三医院 麻醉科
14 13811289616 金姬延 北京大学第三医院 骨科
15 18611302030 张坤 北京大学第三医院 妇科
16 15811123680 邓秀文 北京大学第三医院 肿瘤放疗科
17 15611963578 关里 北京大学第三医院 职业病科
18 15810866570 夏宇曦 北京大学第三医院 医务处
19 13810627171 张迎宏 北京大学第三医院 耳鼻喉
20 15810394568 陈芷谦 北京大学第三医院 老年病内科
21 13810517083 柯嘉 北京大学第三医院 耳鼻喉科
22 13488693118 郝燕婷 北京大学第三医院 老年科
23 18514507016 朱薇 北京大学第三医院 疼痛科
24 13910979132 孙永昌 北京大学第三医院 呼吸内科
25 13521696306 杜俊 北京大学第三医院 医院感染管理处
26 18510967299 方英伦 北京大学第三医院 麻醉科
27 15210502975 雷润宏 北京大学第三医院 放疗科
28 13683363301 林玉晶 北京大学第三医院 老年内科
29 15210907141 刘佳 北京大学第三医院 老年内科
30 13521661293 曲昂 北京大学第三医院 肿瘤放疗科
31 18701567019 李潇潇 北京大学第三医院 药学部
32 13810001444 张晓盈 北京大学第三医院 风湿免疫科
33 15600561969 门鹏 北京大学第三医院 药学部
34 13810388916 杨诗源 北京大学第三医院 超声医学科
35 18839790793 李菲 北京大学第三医院 内分泌科
36 13261875609 宫萍 北京大学第三医院 老年病内科
37 13120336070 么雪婷 北京大学第三医院 药物临床试验机构
38 15201113598 魏枢华 北京大学第三医院 肿瘤放疗科
39 13370137181 李云峰 北京大学第三医院 伤口治疗中心
40 15010341566 王安琪 北京大学第三医院 皮肤科
41 15801376598 王蕊 北京大学第三医院 护理部
42 13522503401 武大伟 北京大学第三医院 耳鼻喉科
43 15652387205 王淑慧 北京大学第三医院 药剂科
44 13321185611 杨丽 北京大学第三医院 药剂科
45 15910965193 王丽嫄 北京大学第三医院 药剂科
46 18810533012 武慧 北京大学第三医院 儿科
47 15611272855 吴捷颖 北京大学第三医院 神经内科
48 13811111694 郭福新 北京大学第三医院 肿瘤放疗科
49 18842627633 刘爽 北京大学第三医院 药学部
50 13041210677 张龙 北京大学第三医院 伤口治疗中心
51 15611908587 苏春燕 北京大学第三医院 肾内科
52 15110158268 胡娴静 北京大学第三医院 护理部
53 18611692313 陈领 北京大学第三医院 伤口治疗中心
54 15010395820 李烜 北京大学第三医院 伤口治疗中心
55 13699176380 王璟 北京大学第三医院 肿瘤化疗与放射病科
56 13141078611 郑伟 北京大学第三医院 神经内科
57 15273111073 许佳琪 北京大学第三医院 普通外科
58 18519650377 张晓静 北京大学第三医院 门诊部
59 15210716367 王艺萌 北京大学第三医院 皮肤科
60 15810292912 胡明奥 北京大学第三医院 骨科
61 18210293651 王晶玭 北京大学第三医院 护理部
62 17812003135 孙文凡 北京大学第三医院 机场住院管理中心
63 13910989410 赵荣生 北京大学第三医院 药学部
64 15010676497 董佳蕙 北京大学第三医院 药学部
65 18811358039 安宇婷 北京大学第三医院 神经外科
66 18310836575 刘泽强 北京大学第三医院 检验科
67 13717959904 周玉洁 北京大学第三医院 普外科
68 13522391517 赵东芳 北京大学第三医院 全科医学科
69 13521115717 郭金竹 北京大学第三医院 皮肤科
70 17837013925 马文静 北京大学第三医院 产科三病房
71 13264046126 荆天意 北京大学第三医院 妇产科
72 15611963829 邓绍晖 北京大学第三医院 泌尿外科
73 13501301199 张艳平 北京大学第三医院 骨科
74 19800308903 王梦瑞 北京大学第三医院 麻醉科
75 15210099011 马莉 北京大学第三医院 急诊科
76 13552930403 强光亮 北京大学第三医院 胸外科
77 13051581652 马善吴 北京大学第三医院 胸外科
78 18511756295 陈凤发 北京大学第三医院 胸外科
79 13651253466 贺未 北京大学第三医院 胸外科
80 13681397086 李桂芬 北京大学第三医院 急诊
81 13810644825 汪宇鹏 北京大学第三医院 心血管内科
82 13811081300 刘文静 北京大学第三医院 感染疾病科
83 13522517275 张玉洁 北京大学第三医院 妇产科
84 17611059621 张晓琦 北京大学第三医院 机场发热急诊
85 18510993486 姜雅楠 北京大学第三医院 儿科
86 13466552713 马媛 北京大学第三医院 心血管内科
87 13520953609 汪宗昱 北京大学第三医院 危重医学科
88 18601309265 闫辉 北京大学第三医院 运动医学
89 15901129743 王晓毅 北京大学第三医院 老年内科
90 18600122874 苗欣 北京大学第三医院 运动医学科
91 17309573451 张辉 北京大学第三医院 感染疾病科
92 15811221023 刘维 北京大学第三医院 药学部
93 18810535187 刘聪颖 北京大学第三医院 心血管内科
94 18810793282 谢鹏昕 北京大学第三医院 心内科
95 15801509989 任佳梦 北京大学第三医院 心内科
96 15026613596 姜熙平 北京大学第三医院 运动医学科
97 15010388257 郑康 北京大学第三医院 急诊科
98 13716250148 谭鲁平 北京大学第三医院 感染疾病科
99 13701366871 焦晨 北京大学第三医院 运动医学
100 17812091912 何华钰 北京大学第三医院 胸外科
101 13811232349 叶剑飞 北京大学第三医院 泌尿外科
102 15611908285 侯小飞 北京大学第三医院 泌尿外科
103 13581517190 宋一萌 北京大学第三医院 泌尿
104 18800198507 张展奕 北京大学第三医院 泌尿外科
105 13810619450 张树栋 北京大学第三医院 泌尿外科
106 13601280387 魏瑗 北京大学第三医院 产科
107 13601375861 王墨培 北京大学第三医院 肿瘤化疗与放射病科
108 13910093201 王欣 北京大学第三医院 眼科
109 13683587263 鲁胜楠 北京大学第三医院 运动医学科
110 15811169856 修萌 北京大学第三医院 肿瘤化疗与放射病科
111 15611908421 王璐 北京大学第三医院 泌尿
112 15810945282 容晓莹 北京大学第三医院 麻醉科
113 13811958963 易福梅 北京大学第三医院 肿瘤化疗与放射病科
114 17778024393 熊振成 北京大学第三医院 胸外科
115 18618451603 宁英泽 北京大学第三医院 胸外科
116 15652930253 林楚童 北京大学第三医院 胸外科
117 19800308315 张秩荻 北京大学第三医院 耳鼻喉科
118 15210197219 严超 北京大学第三医院 耳鼻喉
119 13901193611 杨楠 北京大学第三医院 输血科
120 13520272493 贾博奇 北京大学第三医院 医学工程处
121 15001393084 李倩 北京大学第三医院 肿瘤化疗与放射病科
122 13683207954 皮彦斌 北京大学第三医院 运动医学科
123 13521135624 乔红梅 北京大学第三医院 呼吸科
124 13810944609 王旖旆 北京大学第三医院 医院管理研究所/医务处互联网医院
125 13366621285 乐云逸 北京大学第三医院 内分泌
126 13716382577 杨纨 北京大学第三医院 生殖中心
127 18811199268 解紫钧 北京大学第三医院 眼科
128 13146119710 王凯 北京大学第三医院 呼吸二病房
129 13641391234 张雁林 北京大学第三医院 职业病科
130 13801018940 赵传多 北京大学第三医院 胸外科
131 13810369383 朱明珂 北京大学第三医院 呼吸与危重症医学科
132 15534245986 高旭 北京大学第三医院 感染疾病科
133 18611103019 陈立雪 北京大学第三医院 生殖中心
134 13366448899 庞新亚 北京大学第三医院 胸外科
135 13522535950 汪大伟 北京大学第三医院 人事处
136 18210066530 吴悦 北京大学第三医院 运动医学
137 13466734131 李小涵 北京大学第三医院 机场住院管理中心
138 18627743603 王苏蒙 北京大学第三医院 门诊部
139 18811771533 郭晨霞 北京大学第三医院 呼吸与危重医学科
140 13811854669 刘敬 北京大学第三医院 眼科
141 13616555411 潘佳飞 北京大学第三医院 运动医学科
142 18811097321 赵赞梅 北京大学第三医院 职业病科
143 15001341733 张丛溪 北京大学第三医院 呼吸科
144 13466681757 徐东晓 北京大学第三医院 心内科
145 18612209826 索玲格 北京大学第三医院 眼科
146 18613891959 王蒙 北京大学第三医院 呼吸科
147 13651315864 杨琨 北京大学第三医院 内分泌科
148 13810700702 耿轩 北京大学第三医院 感染疾病科
149 18600640125 申展 北京大学第三医院 眼科
150 13811934661 汪恒 北京大学第三医院 教育处
151 13681384037 张文慧 北京大学第三医院 内分泌科
152 16601101165 王媛媛 北京大学第三医院 妇产科
153 13810970463 何明燕 北京大学第三医院 眼科
154 18518079113 耿春静 北京大学第三医院 麻醉科
155 18810598535 吴天晨 北京大学第三医院 妇产科
156 18210815929 王佳韵 北京大学第三医院 心内科
157 13641088743 徐欣月 北京大学第三医院 心血管内科
158 18511712197 王郝霖霖 北京大学第三医院 心血管内科
159 13910248978 董玥 北京大学第三医院 心内科
160 13683325888 贾珊 北京大学第三医院 医疗美容科
161 13050775099 吴奕璇 北京大学第三医院 生殖中心
162 15001245084 金司爻 北京大学第三医院 药学部
163 13439199415 张莹 北京大学第三医院 疾病预防控制处
164 18710002823 吉喆 北京大学第三医院 肿瘤放疗科
165 18811569934 陈广辉 北京大学第三医院 骨科
166 15501117899 邢珍珍 北京大学第三医院 职业病科
167 15010299379 隋鑫宇 北京大学第三医院 心血管内科
168 18210500535 杨振锟 北京大学第三医院 口腔科
169 13651309071 秦京京 北京大学第三医院 全科
170 13121969380 王松 北京大学第三医院 肾内科
171 18811602096 韩悦 北京大学第三医院 全科医学科
172 13910149228 杨振华 北京大学第三医院 全科医学科
173 13146521125 田金金 北京大学第三医院 体检中心
174 15101597802 王秀会 北京大学第三医院 健康医学科
175 17812168102 宋一帆 北京大学第三医院 全科
176 15117919257 刘珊 北京大学第三医院 健康医学科
177 18701003211 张涛涛 北京大学第三医院 体检中心
178 15652930820 孙晓燕 北京大学第三医院 呼吸
179 19801109952 李彤昕 北京大学第三医院 全科医学科
180 18813037896 李丹 北京大学第三医院 全科医学科
181 18310189257 王晶 北京大学第三医院 心血管内科
182 18610218375 孟亚男 北京大学第三医院 呼吸内科一病房
183 13911533466 张浩琳 北京大学第三医院 中医科
184 13521181273 张星雨 北京大学第三医院 心血管内科
185 13810002686 田勍 北京大学第三医院 内分泌
186 15101021070 魏蕊 北京大学第三医院 内分泌
187 15201303542 姚艳红 北京大学第三医院 肿瘤化疗科
188 13366373225 刘爱华 北京大学第三医院 内分泌科
189 13141213609 马兰 北京大学第三医院 血液科
190 18811771268 汪羚利 北京大学第三医院 血液科
191 13651391951 王闻博 北京大学第三医院 内分泌科
192 13810349928 杨硕 北京大学第三医院 生殖医学科
193 13381281669 闫燕 北京大学第三医院 耳鼻喉
194 13513235782 王悦 北京大学第三医院 内分泌
195 18810887828 张少存 北京大学第三医院 风湿免疫科
196 13126863268 王琛 北京大学第三医院 风湿免疫科
197 13396234497 郭苇 北京大学第三医院 风湿免疫科
198 18600213506 王月麟 北京大学第三医院 眼科
199 18911576658 翟佳羽 北京大学第三医院 风湿免疫科
200 18610121529 王钰 北京大学第三医院 妇科
201 18610121529 王钰 北京大学第三医院 妇科
202 13426248158 周庆涛 北京大学第三医院 呼吸内科
203 15201304342 刘绍清 北京大学第三医院 口腔科
204 13269309414 田小蒙 北京大学第三医院 生殖中心
205 18600017812 赵威 北京大学第三医院 心血管内科、全科医学科
206 13466393220 武睿 北京大学第三医院 病理科
207 13701010401 贺慧颖 北京大学第三医院 病理科
208 15810390491 姚瑶 北京大学第三医院 病理科
209 18801235695 李丹阳 北京大学第三医院 病理科
210 18754278830 季惠惠 北京大学第三医院 病理科
211 13810648499 郑丹枫 北京大学第三医院 病理科
212 13683697009 梅放 北京大学第三医院 病理科
213 13488692897 王惠 北京大学第三医院 病理科
214 15626042244 宋子秀 北京大学第三医院 病理科
215 13651215671 刘从容 北京大学第三医院 病理
216 13269029317 裴斐 北京大学第三医院 病理科
217 18811331969 王玮 北京大学第三医院 病理科
218 15611908149 刘岩 北京大学第三医院 病理科
219 13801211548 杨菁 北京大学第三医院 病理科
220 15210025586 刘士榕 北京大学第三医院 超声医学科
221 13601197736 张雪莹 北京大学第三医院 人事处
222 18610883971 应华 北京大学第三医院 感染疾病科
223 18610883971 应华 北京大学第三医院 感染疾病科
224 18610377492 刘蕊 北京大学第三医院 风湿免疫科
225 18810533283 胡阿锦 北京大学第三医院 病理科
226 13910627163 崔立刚 北京大学第三医院 超声医学科
227 13810920592 高皓宇 北京大学第三医院 医院感染管理处
228 15652249516 白易 北京大学第三医院 医院感染管理处
229 13581530835 王少利 北京大学第三医院 医院感染管理处
230 13681085393 冯香凝 北京大学第三医院 采购管理中心

View File

@@ -0,0 +1,36 @@
手机号,姓名,医院,部门
13426376041,彭荣梅,北京大学第三医院,眼科
18704316131,蔡熙颖,北京大学第三医院,肿瘤放疗科
18132126695,王振宇,北京大学第三医院,肿瘤放疗科
19811941420,林坤鸿,北京大学第三医院,儿科
18340806465,张勇跃,北京大学第三医院,超声医学科
18954565721,王子谦,北京大学第三医院,药剂科
18519393450,李坤宇,北京大学第三医院,药剂科
13311129801,郑雷刚,北京大学第三医院,
18510599667,曲瑞泽,北京大学第三医院,普通外科
15662689682,李夏蕾,北京大学第三医院,药剂科
13960956506,池苗苗,北京大学第三医院,眼科
15611675306,包慧君,北京大学第三医院,
18801482074,赵英涵,北京大学第三医院,眼科
18212101606,刘德福,北京大学第三医院,
19516628985,孙晨哲,北京大学第三医院,
18656031676,徐晨,北京大学第三医院,
13340057914,陈佳钰,北京大学第三医院,超声医学科
15001284388,姚泰康,北京大学第三医院,呼吸与危重症医学科
18701180277,宋欣然,北京大学第三医院,
18810024263,李熳,北京大学第三医院,消化科
13280719719,李睿宁,北京大学第三医院,心血管内科
18897919950,范锐,北京大学第三医院,耳鼻喉科
15960291363,兰麒锋,北京大学第三医院,
18927505128,胡安一,北京大学第三医院,
13247015825,范勇兵,北京大学第三医院,心血管内科
17596528648,裴康佳,北京大学第三医院,肿瘤放疗科
1809314065,王银雪,北京大学第三医院,妇产科
17866625865,刘帅,北京大学第三医院,泌尿外科
17867180629,武瑞,北京大学第三医院,全科医学科
13554870161,丁婧,北京大学第三医院,眼科
18518981091,罗仁杰,北京大学第三医院,普通外科
15897841227,柏佳丽,北京大学第三医院,妇产科
13683324481,汤亚南,北京大学第三医院,儿科
13699255070,杨路,北京大学第三医院,超声科
18377792128,褚岚和,北京大学第三医院,呼吸科
1 手机号 姓名 医院 部门
2 13426376041 彭荣梅 北京大学第三医院 眼科
3 18704316131 蔡熙颖 北京大学第三医院 肿瘤放疗科
4 18132126695 王振宇 北京大学第三医院 肿瘤放疗科
5 19811941420 林坤鸿 北京大学第三医院 儿科
6 18340806465 张勇跃 北京大学第三医院 超声医学科
7 18954565721 王子谦 北京大学第三医院 药剂科
8 18519393450 李坤宇 北京大学第三医院 药剂科
9 13311129801 郑雷刚 北京大学第三医院
10 18510599667 曲瑞泽 北京大学第三医院 普通外科
11 15662689682 李夏蕾 北京大学第三医院 药剂科
12 13960956506 池苗苗 北京大学第三医院 眼科
13 15611675306 包慧君 北京大学第三医院
14 18801482074 赵英涵 北京大学第三医院 眼科
15 18212101606 刘德福 北京大学第三医院
16 19516628985 孙晨哲 北京大学第三医院
17 18656031676 徐晨 北京大学第三医院
18 13340057914 陈佳钰 北京大学第三医院 超声医学科
19 15001284388 姚泰康 北京大学第三医院 呼吸与危重症医学科
20 18701180277 宋欣然 北京大学第三医院
21 18810024263 李熳 北京大学第三医院 消化科
22 13280719719 李睿宁 北京大学第三医院 心血管内科
23 18897919950 范锐 北京大学第三医院 耳鼻喉科
24 15960291363 兰麒锋 北京大学第三医院
25 18927505128 胡安一 北京大学第三医院
26 13247015825 范勇兵 北京大学第三医院 心血管内科
27 17596528648 裴康佳 北京大学第三医院 肿瘤放疗科
28 1809314065 王银雪 北京大学第三医院 妇产科
29 17866625865 刘帅 北京大学第三医院 泌尿外科
30 17867180629 武瑞 北京大学第三医院 全科医学科
31 13554870161 丁婧 北京大学第三医院 眼科
32 18518981091 罗仁杰 北京大学第三医院 普通外科
33 15897841227 柏佳丽 北京大学第三医院 妇产科
34 13683324481 汤亚南 北京大学第三医院 儿科
35 13699255070 杨路 北京大学第三医院 超声科
36 18377792128 褚岚和 北京大学第三医院 呼吸科

View File

@@ -0,0 +1,215 @@
# 旧版本系统 - 服务器与数据库配置说明
> 最后更新2026-02-15
---
## 1. 服务器信息
| 项目 | 值 |
|------|-----|
| 服务器地址 | `8.154.22.149` |
| 操作系统 | Linux (Ubuntu) |
| 数据库类型 | MariaDB |
| 数据库端口 | 3306 |
---
## 2. 数据库连接信息
| 项目 | 值 |
|------|-----|
| 连接地址 | `jdbc:mysql://127.0.0.1:3306/xzyx_online?characterEncoding=utf8` |
| 数据库名 | `xzyx_online` |
| 用户名 | `xzyx_rw` |
| 密码 | `SKJfdwalkd` |
### 命令行连接方式
```bash
# SSH 登录服务器
ssh root@8.154.22.149
# 连接数据库
mysql -u xzyx_rw -p'SKJfdwalkd' -h 127.0.0.1 xzyx_online
```
---
## 3. 用户表结构 (u_user_info)
### 核心字段
| 字段 | 类型 | 说明 | 后台显示名 |
|------|------|------|-----------|
| `id` | int(11) | 主键,自增 | - |
| `phone` | varchar(20) | 手机号(登录账号)**必填** | 账号 |
| `nickname` | varchar(40) | 昵称 | 昵称 |
| `real_name` | varchar(45) | 真实姓名 | - |
| `hospital` | varchar(255) | 固定值 "本地" | - |
| `company` | varchar(200) | **实际的机构/医院名称** | 医院 |
| `academy` | varchar(200) | **部门** | 部门 |
| `user_role` | varchar(20) | 用户角色,默认 "NORMAL" | 用户角色 |
| `user_status` | varchar(45) | 用户状态,默认 "NORMAL" | - |
| `password` | varchar(45) | 密码MD5加密 | - |
| `hosptial_id` | int(11) | 医院ID默认 0 | - |
| `email_validate_status` | tinyint(4) | 邮箱验证状态,默认 0 | - |
| `register_time` | int(11) | 注册时间Unix时间戳 | - |
### 字段对应关系
| 后台显示 | 数据库字段 |
|----------|-----------|
| 账号 | `phone` |
| 昵称 | `nickname` + `real_name` |
| 用户角色:普通 | `user_role = 'NORMAL'` |
| 医院 | `company`(注意:不是 hospital 字段) |
| 部门 | `academy` |
### 默认密码
- 明文:`123456`
- MD5`E10ADC3949BA59ABBE56E057F20F883E`
---
## 4. 批量导入用户操作指南
### 步骤1准备 CSV 文件
格式要求:
```csv
手机号,姓名,医院,部门
13800000001,张三,北京大学第三医院,骨科
13800000002,李四,医朵云,医学部
```
### 步骤2检查重复手机号
```bash
# 导出现有手机号
mysql -u xzyx_rw -p'SKJfdwalkd' -h 127.0.0.1 xzyx_online -N -e "SELECT phone FROM u_user_info;" > /tmp/existing_phones.txt
# 查看现有用户数量
mysql -u xzyx_rw -p'SKJfdwalkd' -h 127.0.0.1 xzyx_online -e "SELECT COUNT(*) FROM u_user_info;"
```
### 步骤3生成 SQL 插入语句
单条插入模板:
```sql
INSERT INTO u_user_info (
phone,
nickname,
real_name,
hospital,
company,
academy,
user_role,
user_status,
password,
hosptial_id,
email_validate_status,
register_time
) VALUES (
'手机号',
'姓名',
'姓名',
'本地',
'机构名称',
'部门',
'NORMAL',
'NORMAL',
'E10ADC3949BA59ABBE56E057F20F883E',
0,
0,
UNIX_TIMESTAMP()
);
```
批量插入模板(使用 INSERT IGNORE 避免重复报错):
```sql
INSERT IGNORE INTO u_user_info (phone, nickname, real_name, hospital, company, academy, user_role, user_status, password, hosptial_id, email_validate_status, register_time) VALUES
('13800000001', '张三', '张三', '本地', '北京大学第三医院', '骨科', 'NORMAL', 'NORMAL', 'E10ADC3949BA59ABBE56E057F20F883E', 0, 0, UNIX_TIMESTAMP()),
('13800000002', '李四', '李四', '本地', '医朵云', '医学部', 'NORMAL', 'NORMAL', 'E10ADC3949BA59ABBE56E057F20F883E', 0, 0, UNIX_TIMESTAMP());
```
### 步骤4上传并执行 SQL
```bash
# 上传 SQL 文件到服务器(或使用 nano 创建)
nano /tmp/batch_insert_users.sql
# 执行 SQL 文件
mysql -u xzyx_rw -p'SKJfdwalkd' -h 127.0.0.1 xzyx_online < /tmp/batch_insert_users.sql
```
### 步骤5验证导入结果
```bash
# 查询指定机构的用户数量
mysql -u xzyx_rw -p'SKJfdwalkd' -h 127.0.0.1 xzyx_online -e "SELECT COUNT(*) as '用户数' FROM u_user_info WHERE company = '北京大学第三医院';"
# 抽查用户数据
mysql -u xzyx_rw -p'SKJfdwalkd' -h 127.0.0.1 xzyx_online -e "SELECT id, phone, nickname, company, academy FROM u_user_info WHERE company = '北京大学第三医院' LIMIT 10;"
```
---
## 5. 常用查询命令
### 查看所有表
```bash
mysql -u xzyx_rw -p'SKJfdwalkd' -h 127.0.0.1 xzyx_online -e "SHOW TABLES;"
```
### 查看表结构
```bash
mysql -u xzyx_rw -p'SKJfdwalkd' -h 127.0.0.1 xzyx_online -e "DESC u_user_info;"
```
### 根据手机号查询用户
```bash
mysql -u xzyx_rw -p'SKJfdwalkd' -h 127.0.0.1 xzyx_online -e "SELECT * FROM u_user_info WHERE phone = '18611348738'\G"
```
### 修改用户信息
```bash
# 修改手机号
mysql -u xzyx_rw -p'SKJfdwalkd' -h 127.0.0.1 xzyx_online -e "UPDATE u_user_info SET phone = '新手机号' WHERE phone = '旧手机号';"
# 重置密码为 123456
mysql -u xzyx_rw -p'SKJfdwalkd' -h 127.0.0.1 xzyx_online -e "UPDATE u_user_info SET password = 'E10ADC3949BA59ABBE56E057F20F883E' WHERE phone = '手机号';"
```
### 删除用户
```bash
mysql -u xzyx_rw -p'SKJfdwalkd' -h 127.0.0.1 xzyx_online -e "DELETE FROM u_user_info WHERE phone = '手机号';"
```
---
## 6. 已导入批次记录
| 批次 | 日期 | 机构 | 数量 | SQL文件 |
|------|------|------|------|---------|
| 第1批 | 2026-02-15 | 北京大学第三医院 | 225 | `docs/06-测试文档/batch_insert_users.sql` |
| 第2批 | 2026-02-15 | 北京大学第三医院 | 35 | `docs/06-测试文档/batch_insert_users_2.sql` |
---
## 7. 注意事项
1. **手机号唯一性**:手机号是用户的唯一登录凭证,不能重复
2. **密码存储**:使用 MD5 加密,默认密码 123456 对应 `E10ADC3949BA59ABBE56E057F20F883E`
3. **hospital 字段**:固定填写 "本地",实际医院名称存储在 `company` 字段
4. **部门字段**:使用 `academy` 字段存储
5. **使用 INSERT IGNORE**:批量导入时使用此语法,遇到重复手机号自动跳过不报错