Files
Orbitin/docs/feishu_data_flow.md
qichi.liang dc2a55bbf4 feat: 添加飞书表格模块支持排班人员信息获取
- 新增 src/feishu_v2.py: 飞书表格API客户端,支持数据库存储和2026年全年排班表
- 新增 src/schedule_database.py: 排班信息数据库模块,用于缓存排班数据
- 新增 docs/feishu_data_flow.md: 飞书数据流文档
- 新增 plans/feishu_scheduling_plan.md: 飞书排班表模块设计文档
- 更新 src/report.py: 使用新的飞书模块获取排班人员信息
- 更新 src/gui.py: 启动时自动获取新数据,添加auto_fetch_data方法
- 更新 .env.example: 添加飞书配置示例
- 更新 AGENTS.md: 更新项目文档
- 更新 main.py: 集成飞书模块

功能特性:
1. 支持从飞书表格获取排班人员信息
2. 支持2025年月度表格和2026年全年排班表
3. 使用SQLite数据库缓存,减少API调用
4. 自动检测表格更新
5. GUI启动时自动获取最新数据
6. 日报中正确显示次日班次人员信息
2025-12-31 00:03:34 +08:00

180 lines
4.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 飞书数据获取流程
## 整体流程
```mermaid
flowchart TD
A[开始: 生成日报] --> B[调用 get_shift_personnel]
B --> C[创建 FeishuScheduleManager]
C --> D[调用 get_schedule_for_date]
D --> E[解析日期: 2025-12-30 → 12/30]
E --> F[检查缓存: data/schedule_cache.json]
F --> G{缓存是否存在?}
G -->|是| H[直接返回缓存数据]
G -->|否| I[调用 API 获取数据]
I --> J[调用 get_sheets_info]
J --> K[GET /spreadsheets/{token}/sheets/query]
K --> L[返回表格列表: 8月, 9月, 10月, 11月, 12月, 2026年...]
L --> M[根据月份选择表格: 12月 → sheet_id='zcYLIk']
M --> N[调用 get_sheet_data]
N --> O[GET /spreadsheets/{token}/values/zcYLIk!A:AF]
O --> P[返回表格数据: 姓名, 12月1日, 12月2日...]
P --> Q[调用 ScheduleDataParser.parse]
Q --> R[解析日期列: 查找12月30日对应的列索引]
R --> S[筛选班次人员: 白班='白', 夜班='夜']
S --> T[返回结果: 白班人员列表, 夜班人员列表]
T --> U[保存到缓存]
U --> V[返回给日报模块]
V --> W[填充到日报中]
```
## API调用详情
### 1. 获取表格列表
**请求**:
```
GET https://open.feishu.cn/open-apis/sheets/v3/spreadsheets/EgNPssi2ghZ7BLtGiTxcIBUmnVh/sheets/query
Authorization: Bearer u-dbctiP9qx1wF.wfoMV2ZHGkh1DNl14oriM8aZMI0026k
```
**响应**:
```json
{
"code": 0,
"data": {
"sheets": [
{"sheet_id": "904236", "title": "8月"},
{"sheet_id": "ATgwLm", "title": "9月"},
{"sheet_id": "2ml4B0", "title": "10月"},
{"sheet_id": "y5xv1D", "title": "11月"},
{"sheet_id": "zcYLIk", "title": "12月"},
{"sheet_id": "R35cIj", "title": "2026年排班表"},
{"sheet_id": "wMXHQg", "title": "12月副本"}
]
}
}
```
### 2. 获取表格数据
**请求**:
```
GET https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/EgNPssi2ghZ7BLtGiTxcIBUmnVh/values/zcYLIk!A:AF
Authorization: Bearer u-dbctiP9qx1wF.wfoMV2ZHGkh1DNl14oriM8aZMI0026k
params: {
valueRenderOption: "ToString",
dateTimeRenderOption: "FormattedString"
}
```
**响应**:
```json
{
"code": 0,
"data": {
"valueRange": {
"range": "zcYLIk!A1:AF11",
"values": [
["姓名", "12月1日", "12月2日", "12月3日", "12月4日", ...],
["张勤", "白", "白", "白", "白", ...],
["刘炜彬", "白", null, "夜", "夜", ...],
["杨俊豪", "白", "白", "白", "白", ...],
["梁启迟", "夜", "夜", "夜", "夜", ...],
...
]
}
}
}
```
## 数据解析流程
### 1. 查找日期列索引
```python
# 查找 "12月30日" 在表头中的位置
headers = ["姓名", "12月1日", "12月2日", ..., "12月30日", ...]
target = "12/30" # 从 "2025-12-30" 转换而来
# 遍历表头找到匹配的日期
for i, header in enumerate(headers):
if header == "12月30日":
column_index = i
break
# 结果: column_index = 31 (第32列)
```
### 2. 筛选班次人员
```python
# 遍历所有人员行
for row in values[1:]: # 跳过表头
name = row[0] # 姓名
shift = row[31] # 12月30日的班次
if shift == "白":
day_shift_list.append(name)
elif shift == "夜":
night_shift_list.append(name)
# 结果
# day_shift_list = ["张勤", "杨俊豪", "冯栋", "汪钦良"]
# night_shift_list = ["刘炜彬", "梁启迟"]
```
### 3. 生成日报输出
```python
day_shift_str = "、".join(day_shift_list) # "张勤、杨俊豪、冯栋、汪钦良"
night_shift_str = "、".join(night_shift_list) # "刘炜彬、梁启迟"
# 日报中的格式
lines.append(f"12/31 白班人员:{day_shift_str}")
lines.append(f"12/31 夜班人员:{night_shift_str}")
```
## 缓存机制
```mermaid
flowchart LR
A[首次请求] --> B[调用API]
B --> C[保存缓存: data/schedule_cache.json]
C --> D{"1小时内再次请求"}
D -->|是| E[直接读取缓存]
D -->|否| F[重新调用API]
```
缓存文件格式:
```json
{
"last_update": "2025-12-30T15:00:00",
"data": {
"2025-12-12/30": {
"day_shift": "张勤、杨俊豪、冯栋、汪钦良",
"night_shift": "刘炜彬、梁启迟",
"day_shift_list": ["张勤", "杨俊豪", "冯栋", "汪钦良"],
"night_shift_list": ["刘炜彬", "梁启迟"]
}
}
}
```
## 关键代码位置
| 功能 | 文件 | 行号 |
|------|------|------|
| 飞书API客户端 | [`src/feishu.py`](src/feishu.py:10) | 10 |
| 获取表格列表 | [`src/feishu.py`](src/feishu.py:28) | 28 |
| 获取表格数据 | [`src/feishu.py`](src/feishu.py:42) | 42 |
| 数据解析器 | [`src/feishu.py`](src/feishu.py:58) | 58 |
| 缓存管理 | [`src/feishu.py`](src/feishu.py:150) | 150 |
| 主管理器 | [`src/feishu.py`](src/feishu.py:190) | 190 |
| 日报集成 | [`src/report.py`](src/report.py:98) | 98 |