# 飞书数据获取流程 ## 整体流程 ```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 |