feat(data-ana): 完整实现 data-ana 数据分析服务
包含 CDC consumer、analytics/mastery/warning service、grpc server、repository、ClickHouse DDL 等
This commit is contained in:
@@ -1,58 +1,386 @@
|
||||
# data-ana 数据分析服务
|
||||
|
||||
> 版本:0.1(P4 骨架)
|
||||
> 端口:3006
|
||||
> 版本:1.0(P4 完整版)
|
||||
> 阶段:D6 智能洞察领域(仲裁已对齐,v2 实现版)
|
||||
> 端口:HTTP 3006(Gateway 直连降级)+ gRPC 50055(主入口,BFF/ai 调用)
|
||||
> 日期:2026-07-10
|
||||
|
||||
## 职责
|
||||
|
||||
数据分析限界上下文(Python 实现),消费 core-edu 与 content 的领域事件,
|
||||
构建 ClickHouse 学情宽表,计算知识点掌握度。
|
||||
对外提供学情仪表盘查询、班级/年级/学校维度报表、个性化推荐数据支撑。
|
||||
数据分析限界上下文(Python/FastAPI 微服务),消费 core-edu / content / iam / ai 的 CDC 事件,
|
||||
构建 ClickHouse 学情宽表,计算知识点掌握度,评估预警,为前端提供 4 端 Dashboard 查询服务。
|
||||
|
||||
### 核心能力
|
||||
|
||||
- **5 张宽表**:student_dashboard_view / student_errors / mastery_snapshot / attendance_logs / ai_usage_log
|
||||
- **CDC 链路**:Debezium → Kafka → data-ana 消费 → ClickHouse(at-least-once + 手动 commit + ReplacingMergeTree 去重)
|
||||
- **掌握度算法**:WEIGHTED_MOVING_AVG(w_i=0.6^i)+ FORGETTING_CURVE(半衰期 30 天)取 max
|
||||
- **预警评估**:5 类预警(LOW_MASTERY / CRITICAL_LOW / SCORE_DROP / ABSENT_FREQUENT / TREND_DECLINE)+ Redis 25h 去重
|
||||
- **DataScope 过滤**:6 级(SELF/CLASS/GRADE/SCHOOL/DISTRICT/ALL),iam gRPC + 角色降级
|
||||
- **gRPC 12 RPC**:AnalyticsService(含 server-streaming SubscribeMasteryUpdate)+ HealthService
|
||||
- **HTTP 14 端点**:3 基础 + 11 业务(ActionState 信封 + degraded 标记)
|
||||
|
||||
## 架构图
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
subgraph Entry["入口层"]
|
||||
HTTP[FastAPI HTTP<br/>:3006 /analytics/* + /healthz + /readyz]
|
||||
GRPC[grpc.aio Server<br/>:50055 AnalyticsService 12 RPC]
|
||||
end
|
||||
|
||||
subgraph Service["应用服务层"]
|
||||
S1[AnalyticsService<br/>4 Dashboard + 班级/趋势查询]
|
||||
S2[MasteryService<br/>掌握度计算 + 事件发布]
|
||||
S3[WarningService<br/>5 类预警 + Redis 去重]
|
||||
end
|
||||
|
||||
subgraph Repo["数据访问层"]
|
||||
R1[ClickHouseRepository<br/>FINAL/argMax + DataScope WHERE]
|
||||
R2[KafkaProducer<br/>mastery.updated 派生事件]
|
||||
R3[IamClient<br/>gRPC GetEffectiveDataScope]
|
||||
R4[RedisClient<br/>DataScope 缓存 + 幂等]
|
||||
end
|
||||
|
||||
subgraph Consumer["CDC 消费者(后台任务)"]
|
||||
C1[CdcConsumer<br/>手动 commit + 7 类事件路由]
|
||||
C2[ExamCache<br/>LRU 10000 exam_id→metadata]
|
||||
end
|
||||
|
||||
subgraph Storage["存储/总线"]
|
||||
CH[(ClickHouse<br/>5 宽表)]
|
||||
KAFKA[(Kafka<br/>edu-cdc.* + edu.insight.mastery.updated)]
|
||||
IAM[iam gRPC :50052]
|
||||
REDIS[(Redis<br/>data_ana:* 键)]
|
||||
end
|
||||
|
||||
HTTP --> S1
|
||||
HTTP --> S3
|
||||
GRPC --> S1
|
||||
S1 --> R1
|
||||
S2 --> R1
|
||||
S2 --> R2
|
||||
S3 --> R1
|
||||
S3 --> R2
|
||||
R1 --> CH
|
||||
R2 --> KAFKA
|
||||
R3 --> IAM
|
||||
R3 --> R4
|
||||
R4 --> REDIS
|
||||
C1 --> C2
|
||||
C1 --> R1
|
||||
C1 --> R4
|
||||
C1 --> KAFKA
|
||||
```
|
||||
|
||||
## 技术栈
|
||||
|
||||
- Python 3.12+ / FastAPI 0.115+
|
||||
- clickhouse-connect(ClickHouse 宽表查询)
|
||||
- pydantic + pydantic-settings(运行时校验与配置)
|
||||
- structlog(结构化日志)
|
||||
- prometheus-client(指标)
|
||||
- OpenTelemetry(分布式追踪)
|
||||
|
||||
## 开发
|
||||
|
||||
```bash
|
||||
uv sync
|
||||
uv run uvicorn src.data_ana.main:app --host 0.0.0.0 --port 3006 --reload
|
||||
```
|
||||
|
||||
## 配置
|
||||
|
||||
| 变量 | 默认值 | 说明 |
|
||||
|------|--------|------|
|
||||
| `PORT` | 3006 | 服务端口 |
|
||||
| `CLICKHOUSE_HOST` | localhost | ClickHouse 主机 |
|
||||
| `CLICKHOUSE_PORT` | 8123 | ClickHouse HTTP 端口 |
|
||||
| `CLICKHOUSE_DATABASE` | edu_analytics | ClickHouse 数据库 |
|
||||
| `OTEL_ENDPOINT` | http://localhost:4318 | OpenTelemetry 端点 |
|
||||
| `LOG_LEVEL` | info | 日志级别 |
|
||||
- **Python 3.12+** / **FastAPI 0.115+**(HTTP 端点)
|
||||
- **grpcio 1.66+** / **grpcio-health-checking**(gRPC server + HealthService)
|
||||
- **clickhouse-connect 0.7+**(ClickHouse 宽表查询,支持 FINAL/argMax)
|
||||
- **aiokafka 0.11+**(CDC 消费者,手动 commit + 幂等去重)
|
||||
- **redis 5.0+**(DataScope 缓存 + 事件去重 + 预警位图)
|
||||
- **pydantic 2.9+** / **pydantic-settings 2.5+**(模型校验 + 配置)
|
||||
- **structlog 24.4+**(结构化 JSON 日志)
|
||||
- **prometheus-client 0.20+**(/metrics 指标)
|
||||
- **opentelemetry-sdk 1.27+**(OTLP 链路追踪)
|
||||
- **protobuf 5.28+**(buf generate 生成的 stub 运行时)
|
||||
|
||||
## 模块结构
|
||||
|
||||
```
|
||||
src/data_ana/
|
||||
├─ __init__.py
|
||||
├─ main.py # FastAPI 入口(健康检查 + 分析端点骨架)
|
||||
├─ config.py # pydantic-settings 配置
|
||||
└─ clickhouse_client.py # ClickHouse 客户端单例
|
||||
├─ main.py # FastAPI 入口(14 端点 + lifespan + ActionState)
|
||||
├─ config.py # pydantic-settings 配置(env_prefix=DATA_ANA_)
|
||||
├─ analytics_service.py # 4 Dashboard + 班级/趋势查询编排
|
||||
├─ mastery_service.py # 掌握度算法(WMA + ForgettingCurve)
|
||||
├─ warning_service.py # 5 类预警评估 + Redis 去重
|
||||
├─ exam_cache.py # LRU exam_id→metadata 映射(max 10000)
|
||||
├─ cdc_consumer.py # CDC 消费者(7 类事件 + 手动 commit)
|
||||
├─ grpc_server.py # 12 RPC + HealthService + SubscribeMasteryUpdate
|
||||
├─ clickhouse_client.py # ClickHouse 客户端单例(降级模式)
|
||||
├─ repository/
|
||||
│ ├─ __init__.py
|
||||
│ ├─ clickhouse_repository.py # 宽表查询 + FINAL/argMax + DataScope WHERE
|
||||
│ ├─ redis_client.py # Redis 异步客户端(cache + dedup + bitmap)
|
||||
│ ├─ iam_client.py # iam gRPC GetEffectiveDataScope + 角色降级
|
||||
│ └─ kafka_producer.py # mastery.updated / warning.triggered 发布
|
||||
└─ shared/
|
||||
├─ __init__.py
|
||||
├─ action_state.py # ActionState[T] 统一信封(ok/fail + degraded)
|
||||
├─ errors.py # ErrorCode 13 类 + DataAnaError
|
||||
└─ permissions.py # 权限点 + DataScopeLevel + build_datascope_where
|
||||
```
|
||||
|
||||
## 关键端点
|
||||
## 开发
|
||||
|
||||
- `GET /healthz` 健康检查
|
||||
- `GET /metrics` Prometheus 指标
|
||||
- `GET /analytics/class/{class_id}/performance` 班级成绩分析(P4 骨架)
|
||||
- `GET /analytics/student/{student_id}/weakness` 学生薄弱知识点分析(P4 骨架)
|
||||
```bash
|
||||
# 安装依赖
|
||||
uv sync
|
||||
|
||||
# 本地开发(HTTP + gRPC + CDC 同时启动)
|
||||
uv run uvicorn src.data_ana.main:app --host 0.0.0.0 --port 3006 --reload
|
||||
|
||||
# ruff 校验
|
||||
ruff check src/
|
||||
|
||||
# 类型检查(如已配置 mypy)
|
||||
mypy src/
|
||||
```
|
||||
|
||||
## 配置项
|
||||
|
||||
所有配置使用 `DATA_ANA_` 前缀(pydantic-settings env_prefix)。
|
||||
|
||||
### 基础配置
|
||||
|
||||
| 变量 | 默认值 | 说明 |
|
||||
| ------------------------ | --------------------- | ------------------------------------ |
|
||||
| `DATA_ANA_HTTP_PORT` | 3006 | HTTP 端口(Gateway 直连降级) |
|
||||
| `DATA_ANA_GRPC_PORT` | 50055 | gRPC 端口(AnalyticsService 主入口) |
|
||||
| `DATA_ANA_DEV_MODE` | true | 开发模式(关闭签名校验) |
|
||||
| `DATA_ANA_LOG_LEVEL` | info | 日志级别(debug/info/warning/error) |
|
||||
| `DATA_ANA_OTEL_ENDPOINT` | http://localhost:4318 | OpenTelemetry OTLP 端点 |
|
||||
|
||||
### 外部依赖(全部可选,未配置则降级模式)
|
||||
|
||||
| 变量 | 默认值 | 说明 |
|
||||
| ------------------------------ | ------------- | ------------------------------------------ |
|
||||
| `DATA_ANA_CLICKHOUSE_HOST` | "" | ClickHouse 主机(空字符串=降级模式) |
|
||||
| `DATA_ANA_CLICKHOUSE_PORT` | 8123 | ClickHouse HTTP 端口 |
|
||||
| `DATA_ANA_CLICKHOUSE_DATABASE` | edu_analytics | ClickHouse 数据库 |
|
||||
| `DATA_ANA_CLICKHOUSE_USER` | "" | ClickHouse 用户名 |
|
||||
| `DATA_ANA_CLICKHOUSE_PASSWORD` | "" | ClickHouse 密码 |
|
||||
| `DATA_ANA_KAFKA_BROKERS` | "" | Kafka broker 列表(逗号分隔,空=禁用 CDC) |
|
||||
| `DATA_ANA_KAFKA_GROUP_ID` | data-ana-cdc | 消费者组 ID |
|
||||
| `DATA_ANA_REDIS_URL` | "" | Redis URL(空=禁用缓存/去重) |
|
||||
| `DATA_ANA_IAM_GRPC_ENDPOINT` | "" | iam gRPC 端点(空=角色降级) |
|
||||
|
||||
### 降级模式说明
|
||||
|
||||
- **ClickHouse 未配置/不可达**:查询返回骨架数据(空数组 + degraded=true)
|
||||
- **Kafka 未配置**:CDC 消费者不启动,`/readyz` 仍就绪
|
||||
- **Redis 未配置/不可达**:缓存失效,每次查询重新计算 DataScope
|
||||
- **iam gRPC 未配置/不可达**:基于 JWT 角色 fallback(teacher→CLASS,student→SELF)
|
||||
- **grpcio 未安装**:gRPC server 不启动,HTTP 仍可用
|
||||
|
||||
## 端点清单
|
||||
|
||||
### 基础端点(3 个)
|
||||
|
||||
| 方法 | 路径 | 说明 |
|
||||
| ---- | ---------- | ----------------------------------------------------------- |
|
||||
| GET | `/` | 根信息(服务名/版本/端点列表) |
|
||||
| GET | `/healthz` | liveness 检查(进程存活即 ok) |
|
||||
| GET | `/readyz` | readiness 检查(5 依赖状态:clickhouse/cdc/redis/iam/grpc) |
|
||||
| GET | `/metrics` | Prometheus 指标 |
|
||||
|
||||
### 业务端点(11 个,全部返回 ActionState[T])
|
||||
|
||||
| 方法 | 路径 | 说明 |
|
||||
| ---- | -------------------------------------------------- | ------------------------------- |
|
||||
| GET | `/analytics/class/{class_id}/performance` | 班级成绩分析(平均分/及格率) |
|
||||
| GET | `/analytics/class/{class_id}/mastery-distribution` | 班级掌握度分布(三档) |
|
||||
| GET | `/analytics/student/{student_id}/weakness` | 学生薄弱知识点(mastery < 0.6) |
|
||||
| GET | `/analytics/student/{student_id}/mastery` | 学生掌握度明细 |
|
||||
| GET | `/analytics/student/{student_id}/trend` | 学习趋势(历史成绩曲线) |
|
||||
| GET | `/analytics/student/{student_id}/errorbook` | 学生错题本 |
|
||||
| GET | `/analytics/teacher/dashboard` | 教师仪表盘 |
|
||||
| GET | `/analytics/student/dashboard` | 学生仪表盘 |
|
||||
| GET | `/analytics/parent/dashboard` | 家长仪表盘 |
|
||||
| GET | `/analytics/admin/dashboard` | 管理员仪表盘 |
|
||||
| GET | `/analytics/warnings` | 预警列表 |
|
||||
| POST | `/analytics/warnings/trigger` | 手动触发预警 |
|
||||
|
||||
### ActionState 信封格式
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": { ... },
|
||||
"details": {
|
||||
"degraded": false,
|
||||
"degraded_reason": ""
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
降级时 `degraded=true`,`data` 返回骨架数据(空数组/零值)。
|
||||
|
||||
## gRPC 契约
|
||||
|
||||
### AnalyticsService(12 RPC,端口 50055)
|
||||
|
||||
| RPC | 类型 | 说明 |
|
||||
| ---------------------- | ---------------- | ----------------------------------- |
|
||||
| GetClassPerformance | unary | 班级成绩分析 |
|
||||
| GetStudentWeakness | unary | 学生薄弱知识点 |
|
||||
| GetLearningTrend | unary | 学习趋势 |
|
||||
| GetTeacherDashboard | unary | 教师仪表盘 |
|
||||
| GetStudentDashboard | unary | 学生仪表盘 |
|
||||
| GetParentDashboard | unary | 家长仪表盘 |
|
||||
| GetAdminDashboard | unary | 管理员仪表盘 |
|
||||
| GetWarnings | unary | 预警列表 |
|
||||
| TriggerWarning | unary | 手动触发预警 |
|
||||
| GetMasteryDistribution | unary | 班级掌握度分布 |
|
||||
| GetStudentMastery | unary | 学生掌握度明细 |
|
||||
| SubscribeMasteryUpdate | server-streaming | 掌握度更新订阅(P5+ AI 个性化通道) |
|
||||
|
||||
### HealthService
|
||||
|
||||
`grpc.health.v1.Health` 标准 K8s 探针。
|
||||
|
||||
### proto 定义
|
||||
|
||||
- `packages/shared-proto/proto/analytics.proto`(12 RPC + 全部消息)
|
||||
- `packages/shared-proto/proto/events.proto`(MasteryEvent + AIUsageEvent)
|
||||
- `packages/shared-proto/proto/iam.proto`(GetEffectiveDataScope)
|
||||
|
||||
## CDC 事件消费
|
||||
|
||||
### 消费的 7 类事件
|
||||
|
||||
| 事件源 | Topic | 处理 |
|
||||
| ------------------------ | ------------------------------------------------- | ------------------------- |
|
||||
| core-edu.exams | `edu-cdc.next_edu_cloud.core_edu_exams` | 写 exam_cache |
|
||||
| core-edu.grades | `edu-cdc.next_edu_cloud.core_edu_grades` | 写 student_dashboard_view |
|
||||
| core-edu.homework | `edu-cdc.next_edu_cloud.core_edu_homework` | 写 student_dashboard_view |
|
||||
| core-edu.attendance | `edu-cdc.next_edu_cloud.core_edu_attendance` | 写 attendance_logs |
|
||||
| content.knowledge_points | `edu-cdc.next_edu_cloud.content_knowledge_points` | 知识点元数据 |
|
||||
| ai.ai_usage | `edu.insight.ai.usage` | 写 ai_usage_log |
|
||||
|
||||
### 幂等保证
|
||||
|
||||
- **Kafka producer**:`enable_idempotence=True` + `transactional_id`
|
||||
- **Consumer 去重**:Redis SETNX `data_ana:dedup:{event_id}` TTL 7 天
|
||||
- **ClickHouse 去重**:ReplacingMergeTree(last_updated) + FINAL/argMax 查询
|
||||
- **手动 commit**:仅在 ClickHouse 写入成功后 commit(at-least-once 语义)
|
||||
|
||||
## 发布的派生数据事件
|
||||
|
||||
| 事件 | Topic | 触发条件 | Outbox 豁免 |
|
||||
| ---------------- | ------------------------------------- | -------------- | ----------------------- |
|
||||
| MasteryUpdated | `edu.insight.mastery.updated` | 掌握度计算完成 | ✅(004 §12.2 仲裁) |
|
||||
| WarningTriggered | `edu.insight.mastery.updated`(复用) | 预警阈值触发 | ✅(004 §15.3 #6 仲裁) |
|
||||
|
||||
> Outbox 豁免理由:派生数据事件,无业务状态变更,重复消费幂等。
|
||||
|
||||
## ClickHouse 宽表
|
||||
|
||||
DDL 位置:`scripts/clickhouse-init.sql`
|
||||
|
||||
| 表名 | 引擎 | ORDER BY | 用途 |
|
||||
| ---------------------- | ----------------------------------- | ----------------------------------------------- | -------------- |
|
||||
| student_dashboard_view | ReplacingMergeTree(last_updated) | (student_id, exam_id, knowledge_point_id) | 学情宽表 |
|
||||
| student_errors | ReplacingMergeTree(last_error_time) | (student_id, question_id) | 错题本 |
|
||||
| mastery_snapshot | MergeTree | (student_id, knowledge_point_id, calculated_at) | 掌握度历史快照 |
|
||||
| ai_usage_log | ReplacingMergeTree(occurred_at) | (request_id,) | AI 用量计费 |
|
||||
| attendance_logs | ReplacingMergeTree(occurred_at) | (student_id, class_id, attendance_date) | 考勤记录 |
|
||||
|
||||
Mock 数据:`scripts/data-ana-mock-data.sql`
|
||||
|
||||
## 掌握度算法
|
||||
|
||||
### 公式
|
||||
|
||||
```
|
||||
mastery = max(WMA, ForgettingCurve)
|
||||
|
||||
WMA = Σ(w_i * score_i) / Σ(w_i), w_i = 0.6^i (近 5 次,权重递减)
|
||||
|
||||
ForgettingCurve = last_mastery * exp(-ln(2) * days_since / 30)
|
||||
```
|
||||
|
||||
### 分类
|
||||
|
||||
| 区间 | label | 说明 |
|
||||
| --------- | ----------- | ------ |
|
||||
| ≥ 0.8 | mastered | 已掌握 |
|
||||
| 0.4 - 0.8 | progressing | 进展中 |
|
||||
| < 0.4 | weak | 薄弱 |
|
||||
|
||||
### 降级规则
|
||||
|
||||
- 近 5 次成绩不足 5 次 → 降级 SIMPLE_AVG
|
||||
- 无历史数据 → 返回 0.0 + label=weak
|
||||
|
||||
## 预警类型
|
||||
|
||||
| 类型 | 阈值 | severity | 说明 |
|
||||
| --------------- | ------------- | -------- | -------- |
|
||||
| LOW_MASTERY | mastery < 0.4 | WARN | 掌握度低 |
|
||||
| CRITICAL_LOW | mastery < 0.2 | CRITICAL | 严重低 |
|
||||
| SCORE_DROP | 下降 ≥ 20% | WARN | 成绩下降 |
|
||||
| ABSENT_FREQUENT | ≥ 3 次/周 | WARN | 频繁缺勤 |
|
||||
| TREND_DECLINE | 连续 3 次降 | INFO | 趋势下降 |
|
||||
|
||||
### 去重
|
||||
|
||||
- Redis key:`data_ana:warning:{target_id}:{type}:{date}`
|
||||
- TTL:25 小时(跨日保证)
|
||||
|
||||
## DataScope 过滤
|
||||
|
||||
### 6 级
|
||||
|
||||
| 级别 | scope_ids 含义 |
|
||||
| -------- | --------------------- |
|
||||
| SELF | 学生本人 ID |
|
||||
| CLASS | 可见 class_id 列表 |
|
||||
| GRADE | 可见 grade_id 列表 |
|
||||
| SCHOOL | 可见 school_id 列表 |
|
||||
| DISTRICT | 可见 district_id 列表 |
|
||||
| ALL | 无过滤 |
|
||||
|
||||
### 解析链
|
||||
|
||||
```
|
||||
请求 → Redis 缓存(5min)→ iam gRPC GetEffectiveDataScope → 角色降级 fallback
|
||||
```
|
||||
|
||||
### 角色降级(iam 不可用时)
|
||||
|
||||
| JWT 角色 | 降级 scope |
|
||||
| -------- | --------------------- |
|
||||
| teacher | CLASS(自己教的班级) |
|
||||
| student | SELF(本人) |
|
||||
| parent | SELF(本人 + 孩子) |
|
||||
| admin | ALL |
|
||||
|
||||
## 部署
|
||||
|
||||
### Docker
|
||||
|
||||
```bash
|
||||
# 构建(多阶段:builder + runtime)
|
||||
docker build -t data-ana:1.0.0 services/data-ana/
|
||||
|
||||
# 运行(需 ClickHouse/Kafka/Redis 可达)
|
||||
docker run -p 3006:3006 -p 50055:50055 \
|
||||
-e DATA_ANA_CLICKHOUSE_HOST=clickhouse \
|
||||
-e DATA_ANA_KAFKA_BROKERS=kafka:9092 \
|
||||
-e DATA_ANA_REDIS_URL=redis://redis:6379 \
|
||||
data-ana:1.0.0
|
||||
```
|
||||
|
||||
### 健康检查
|
||||
|
||||
- HTTP `/healthz`:进程存活即 ok
|
||||
- HTTP `/readyz`:检查 5 依赖(clickhouse/cdc/redis/iam/grpc)
|
||||
- gRPC `grpc.health.v1.Health`:K8s 探针
|
||||
|
||||
## 对外契约
|
||||
|
||||
gRPC 服务 `AnalyticsService` 定义见 `packages/shared-proto/proto/analytics.proto`。
|
||||
- **gRPC proto**:`packages/shared-proto/proto/analytics.proto`
|
||||
- **HTTP OpenAPI**:启动后访问 `/docs`
|
||||
- **CDC topic 命名**:`edu-cdc.next_edu_cloud.<table>`(Debezium 标准)
|
||||
- **派生事件 topic**:`edu.insight.mastery.updated` / `edu.insight.ai.usage`
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [02-architecture-design.md](./docs/02-architecture-design.md):模块架构设计 v2(仲裁后)
|
||||
- [01-understanding.md](./docs/01-understanding.md):阶段 1 理解确认书
|
||||
- [004 架构影响地图 §15.3](../../docs/architecture/004_architecture_impact_map.md):coord 仲裁结论
|
||||
- [coord-cross-review.md](../../docs/architecture/coord-cross-review.md):交叉审查记录
|
||||
- [known-issues §2.6](../../docs/troubleshooting/known-issues.md):data-ana 已知问题速查
|
||||
|
||||
Reference in New Issue
Block a user