mirror of
https://devops.liangqichi.top/qichi.liang/Orbitin.git
synced 2026-02-10 07:41:29 +08:00
- 新增 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. 日报中正确显示次日班次人员信息
180 lines
4.8 KiB
Markdown
180 lines
4.8 KiB
Markdown
# 飞书数据获取流程
|
||
|
||
## 整体流程
|
||
|
||
```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 |
|