620 lines
28 KiB
Markdown
620 lines
28 KiB
Markdown
# 考勤报表导出参考 (attendance-report)
|
||
|
||
> 本文档由 `attendance.md` 路由调用。当用户提到"考勤报表"、"导出考勤"、"出勤汇总"、"考勤明细"、"迟到早退统计"、"全员考勤数据"、"某月考勤统计"、"考勤表格"、"考勤 Excel" 时,应阅读本文档执行。
|
||
> 不适用于:个人单日打卡查询(用 `attendance check record`)、班次查询(用 `attendance schedule get`)、假期余额(用 `vacation balance`)、审批进度(用 `oa`)。
|
||
|
||
## 强制门禁(必须先读完本文档才能执行)
|
||
|
||
**任何调用 `attendance_report_detail.py` / `attendance_report_monthly.py` / `attendance_report_daily.py` 的请求,都必须经过本文档定义的工作流,严禁绕过本文档直接拼脚本命令执行。**
|
||
|
||
违反将出现以下任一问题:
|
||
1. 未按"阶段 1"做人员解析 → `--users` 传入部门 ID 而非员工 userId,脚本虽内置回退但会浪费一次失败的接口调用
|
||
2. 未按"阶段 0"判断报表类型 → 用户说"汇总"被理解成"明细",导致输出粒度错误
|
||
3. 未按"列选择"判断是否传 `--column-keywords` → 用户要"迟到情况报表"被输出成全字段默认报表
|
||
4. 未按"错误处理"规则处理 403 / `HSF_ILLEGALPARAMS` → 把环境错误当成业务错误反馈给用户
|
||
5. 未按"阶段 4"返回结果 → 把 Excel 内容贴在对话里,或者裸 userId 直接输出
|
||
|
||
**执行前自检(必须能在心中回答)**:
|
||
- [ ] 报表类型是?(明细 / 月度汇总 / 每日统计)
|
||
- [ ] 人员列表的来源是?(`aisearch person` 还是 `contact dept list-members`?)
|
||
- [ ] 列选择方式是?(预设报表关键词 / 自定义 `--column-keywords` / 默认列集合)
|
||
- [ ] 报错时如何向用户解释?
|
||
|
||
如果上述任何一项答不出,**回到本文档对应章节重新阅读**,禁止凭记忆/想象组装命令。
|
||
|
||
**前提**:当前用户必须是钉钉管理员,否则 report 系列接口返回 403 权限错误。
|
||
|
||
## 核心原则
|
||
|
||
Agent 解析用户意图(报表类型、人员范围、时间范围、关注维度),获取 userId 列表后,**直接调用对应的 Python 脚本 CLI 生成 Excel**。
|
||
- **脚本自包含**:数据查询(分批、分段、翻页)、字段解析、聚合计算、Excel 生成全部由脚本内部完成,Agent 不参与数据查询和计算
|
||
- **月度汇总 / 每日统计**:脚本内部调用 `report columns` + `report query-data`
|
||
- **明细**:脚本内部调用 `check result` + `check record`(数据源不同)
|
||
- 列选择是独立维度:用户未指定关注维度时脚本使用内置默认字段;用户指定了关注维度时 Agent 通过 `--column-keywords` 参数传给脚本
|
||
|
||
## 严格禁止 (NEVER DO)
|
||
|
||
- 禁止凭历史记忆复用 userId 等任何 ID,必须从当次命令返回值中提取
|
||
- 禁止用大模型口算/目测做考勤数据聚合(求和、计数、分组),必须通过 Python 脚本完成
|
||
- 禁止 Agent 直接调用 `report query-data` / `report columns` / `check result` / `check record`,这些由脚本内部自动完成
|
||
- 禁止 `dws` 命令缺省 `--format json`(Agent 仅在阶段 1 获取人员时直接调用 dws 命令)
|
||
- 禁止编造任何字段值或用户姓名
|
||
- 禁止直接输出裸 userId,脚本已内置 userId → 姓名转换
|
||
|
||
## 严格要求 (MUST DO)
|
||
|
||
- 所有 `dws` 命令必须携带 `--format json`
|
||
- 时间参数 `--start` / `--end` 格式必须为 `yyyy-MM-dd HH:mm:ss`
|
||
- 字段 ID 与字段名的映射必须从 `report columns` 实时建立,禁止硬编码
|
||
- 任何接口失败(含 403)必须向用户清晰报错,禁止静默吞掉
|
||
|
||
## 涉及工具
|
||
|
||
| 工具 | 用途 | 安全等级 |
|
||
|------|------|---------|
|
||
| `dws attendance report columns` | 获取当前管理员可见的考勤字段清单(字段 ID → 字段名) | 只读 |
|
||
| `dws attendance report query-data` | 按字段查询考勤数据(≤20 人/次,≤32 天/次) | 只读 |
|
||
| `dws attendance report query-leave` | 按假期名称查询假期数据(≤20 人/次,≤32 天/次),月度汇总/每日统计的"请假"列由脚本自动调用 | 只读 |
|
||
| `dws attendance approve list` | 查询审批单记录(考勤记录报表专用),支持类型:leave/trip/out/patch | 只读 |
|
||
| `dws oa approval detail` | 获取审批单详情(考勤记录报表专用),解析 formValueVOS / extValue | 只读 |
|
||
| `dws attendance check result` | 查询打卡结果(≤100 人/次,≤1 月,明细报表专用) | 只读 |
|
||
| `dws attendance check record` | 查询打卡流水(≤1 月,明细报表专用) | 只读 |
|
||
| `dws aisearch person` | 按姓名搜索用户获取 userId(搜人首选) | 只读 |
|
||
| `dws contact user get` | 批量查询 userId → 用户信息(姓名/部门/工号/职位) | 只读 |
|
||
| `dws contact dept search` | 搜索部门获取 deptId | 只读 |
|
||
| `dws contact dept list-members` | 获取部门成员 userId 列表 | 只读 |
|
||
|
||
## 意图判断
|
||
|
||
### 报表类型(五选一)
|
||
|
||
| 用户说 | 报表类型 | 映射脚本 |
|
||
|--------|---------|---------|
|
||
| "导出研发部 3 月份的考勤明细" / "每条打卡记录" / "明细" / "原始记录" | 明细 | `attendance_report_detail.py` |
|
||
| "生成研发部 3 月考勤汇总" / 用户明确说"月度汇总" / 用户未指明类型 | **月度汇总(默认)** | `attendance_report_monthly.py` |
|
||
| "导出研发部 3 月每天的出勤情况" / "按天统计" / "每日" / 用户明确说"每日统计" | 每日统计 | `attendance_report_daily.py` |
|
||
| "导出研发部 4 月的请假记录" / "补卡记录" / "出差记录" / "外出记录" / "xx记录" | 考勤记录 | `attendance_report_record.py` |
|
||
| "导出签到记录" / "签到报表" / "签到数据导出" / "签到明细" / "外勤签到" | 签到报表 | `attendance_report_checkin.py` |
|
||
|
||
> **默认报表类型**:用户未指明报表类型时,**默认走月度汇总**,事后告知"已按月度汇总输出,如需明细/每日统计/考勤记录请告知"。
|
||
>
|
||
> **考勤记录 vs 其他报表**:当用户明确提到"请假记录"/"补卡记录"/"出差记录"/"外出记录"时,走考勤记录报表(数据源为审批单)。而"请假报表"/"出差时长统计"等走月度汇总(数据源为 report query-data)。区别在于:考勤记录导出的是**审批单维度的原始数据**(含审批单状态、每天明细),月度汇总导出的是**按人按月聚合后的统计数据**。
|
||
|
||
### 列选择(独立维度,与报表类型正交)
|
||
|
||
> **"报表类型"与"列选择"是两个独立维度,需分别判断。**
|
||
> 例如用户说"帮我出一份加班报表":报表类型未指明 → 默认月度汇总;列选择命中"加班报表" → 使用加班预设关键词。
|
||
> 例如用户说"帮我出每日的异常报表":报表类型命中"每日" → 每日统计脚本;列选择命中"异常报表" → 使用异常预设关键词。
|
||
> 预设报表**不会改变报表类型的判断逻辑**,报表类型始终按下方「报表类型(三选一)」规则判断。
|
||
|
||
| 用户说 | 列选择方式 |
|
||
|--------|-----------|
|
||
| "帮我出一份考勤报表" / "导出考勤" / 未提及特定关注维度 | 不传 `--column-keywords`,使用脚本内置**默认列集合** |
|
||
| "加班报表" / "加班统计" / "加班时长报表" | 传 `--column-keywords`,使用下方「加班报表预设关键词」 |
|
||
| "请假报表" / "请假出差报表" / "请假外出统计" | 传 `--column-keywords`,使用下方「请假报表预设关键词」 |
|
||
| "异常报表" / "异常考勤" / "迟到早退报表" / "缺卡报表" | 传 `--column-keywords`,使用下方「异常报表预设关键词」 |
|
||
| 提及了其他自定义关注维度(如"工作时长报表") | 传 `--column-keywords`,由 Agent 自行拼接关键词 |
|
||
|
||
> **预设报表优先级**:当用户提到的关键词同时命中"预设报表"和一般自定义维度时,**优先使用预设报表的完整关键词列表**,确保列不遗漏。
|
||
|
||
### 易混淆场景
|
||
|
||
| 用户说 | 应路由到 |
|
||
|--------|---------|
|
||
| "今天打卡了吗" | `dws attendance record get`(单次查询,非报表) |
|
||
| "帮我排班" | `dws attendance schedule import`(导入排班,非报表;先确认考勤组、人员、日期、班次和休息日) |
|
||
| "我的假期还剩多少" | `dws attendance vacation balance`(单次查询) |
|
||
| "帮我请假" | `dws oa`(审批流程,非报表) |
|
||
| "我这个月的考勤怎么样" | `dws attendance summary`(个人统计,非报表) |
|
||
|
||
## 工作流
|
||
|
||
### 阶段 0: 参数解析与确认查询范围
|
||
|
||
1. **解析用户输入**(两个独立维度):
|
||
- **报表类型**(四选一):明细 / 月度汇总(默认) / 每日统计 / 考勤记录
|
||
- **列选择**(独立维度):预定义列集合(默认) / 用户指定维度筛选(考勤记录不适用)
|
||
- **人员维度**:指定员工 / 某个部门 / 多个部门(暂不支持全公司查询)
|
||
- **时间维度**:本周 / 本月 / 自定义时间段
|
||
- **记录子类型**(仅考勤记录):leave(请假) / trip(出差) / out(外出) / patch(补卡)
|
||
2. **缺失信息处理**:
|
||
- **报表类型** 缺失 → 默认走月度汇总(不追问),事后告知
|
||
- **列选择**:用户提及了特定关注维度 → 传 `--column-keywords`;未提及 → 使用脚本内置默认字段集
|
||
- **用户范围 / 时间范围** 缺失 → 追问,禁止猜测
|
||
|
||
### 阶段 1: 获取完整人员列表
|
||
|
||
**场景 A — 指定员工姓名**:
|
||
```bash
|
||
dws aisearch person --query "<员工姓名>" --dimension name --format json
|
||
```
|
||
|
||
**场景 B — 按部门查询**:
|
||
```bash
|
||
dws contact dept search --query "<部门名>" --format json
|
||
dws contact dept list-members --ids <deptId> --format json
|
||
```
|
||
|
||
**场景 C — 多个部门**: 对每个部门分别执行 B,汇总去重。
|
||
|
||
**场景 D — 全公司**: 暂不支持,引导用户指定部门。
|
||
|
||
**场景 E — 用户已给 userId 列表**: 直接跳过本步。
|
||
|
||
### 阶段 2: 列选择(决定脚本参数)
|
||
|
||
> Agent 不需要手动调用 `report columns`,字段获取由脚本内部完成。Agent 只需根据用户意图决定是否传 `--column-keywords` 参数。
|
||
|
||
**判断顺序**(优先级从高到低):
|
||
|
||
1. **明细报表** → 列固定,不支持 `--column-keywords`
|
||
2. **用户提到预设报表关键词** → 传 `--column-keywords`,使用本文档「预设报表列集合」中定义的完整关键词列表:
|
||
- "加班报表" / "加班统计" / "加班时长" → 使用「加班报表预设关键词」
|
||
- "请假报表" / "请假出差" / "外出统计" → 使用「请假报表预设关键词」
|
||
- "异常报表" / "迟到早退" / "缺卡报表" / "异常考勤" → 使用「异常报表预设关键词」
|
||
3. **用户提及了其他自定义关注维度** → 传 `--column-keywords "..."`
|
||
4. **用户未提及特定关注维度** → 不传 `--column-keywords`,脚本使用内置默认字段集
|
||
|
||
### 阶段 3: 调用脚本生成 Excel
|
||
|
||
#### 月度汇总 / 每日统计
|
||
|
||
```bash
|
||
python scripts/attendance_report_monthly.py \
|
||
--users <userId1>,<userId2>,... \
|
||
--start "<yyyy-MM-dd>" \
|
||
--end "<yyyy-MM-dd>" \
|
||
[--column-keywords "出勤天数,迟到次数,迟到时长,..."] \
|
||
[--out 月度汇总_研发部_202604.xlsx]
|
||
```
|
||
|
||
参数说明:
|
||
- `--users`(必填):逗号分隔的 userId 列表
|
||
- `--start`(必填):开始日期,支持 `YYYY-MM-DD` 或 `YYYY-MM-DD HH:mm:ss`
|
||
- `--end`(必填):结束日期,同上
|
||
- `--column-keywords`(可选):逗号分隔的字段名关键词。不传则使用脚本内置默认字段集。预设报表(加班/请假/异常)也通过本参数传入对应的预设关键词列表
|
||
- `--out`(可选):输出文件名,不传则自动生成
|
||
|
||
脚本内部自动处理:`report columns` 获取字段清单 → 按预设/关键词匹配 → `report query-data` 分批分段查询 → `contact user get` 姓名映射 → 聚合计算 → 生成 Excel
|
||
|
||
#### 明细
|
||
|
||
```bash
|
||
python scripts/attendance_report_detail.py \
|
||
--users <userId1>,<userId2>,... \
|
||
--start "<yyyy-MM-dd>" \
|
||
--end "<yyyy-MM-dd>" \
|
||
[--out 考勤明细_研发部_202604.xlsx]
|
||
```
|
||
|
||
- **没有 `--column-keywords`**,明细列固定
|
||
- 数据来源不同:`check result` + `check record`(非 `report query-data`)
|
||
- 分批限制:≤100 人/次(而非 20 人)
|
||
|
||
#### 考勤记录
|
||
|
||
```bash
|
||
python scripts/attendance_report_record.py \
|
||
--type <leave|trip|out|patch> \
|
||
--users <userId1>,<userId2>,... \
|
||
--start "<yyyy-MM-dd>" \
|
||
--end "<yyyy-MM-dd>" \
|
||
[--out 请假记录_研发部_202604.xlsx]
|
||
```
|
||
|
||
参数说明:
|
||
- `--type`(必填):记录类型,支持 `leave`(请假) / `trip`(出差) / `out`(外出) / `patch`(补卡)
|
||
- `--users`(必填):逗号分隔的 userId 列表
|
||
- `--start`(必填):开始日期 `YYYY-MM-DD`
|
||
- `--end`(必填):结束日期 `YYYY-MM-DD`
|
||
- `--out`(可选):输出文件名,不传则自动生成
|
||
- **没有 `--column-keywords`**,列由 `--type` 决定
|
||
|
||
脚本内部自动处理:`attendance approve list` 获取审批摘要 → `oa approval detail` 获取详情 → 解析 DDHolidayField / extValue → 按天拆行 → `contact user get` 姓名映射 → 生成 Excel
|
||
|
||
**记录类型选择规则**(Agent 需从用户意图中判断):
|
||
|
||
| 用户说 | --type 值 |
|
||
|--------|----------|
|
||
| "请假记录" / "年假记录" / "调休记录" / "病假记录" | `leave` |
|
||
| "出差记录" | `trip` |
|
||
| "外出记录" | `out` |
|
||
| "补卡记录" | `patch` |
|
||
|
||
#### 签到报表
|
||
|
||
```bash
|
||
python scripts/attendance_report_checkin.py \
|
||
--users <userId1>,<userId2>,... \
|
||
--start "<yyyy-MM-dd>" \
|
||
--end "<yyyy-MM-dd>" \
|
||
[--out 签到报表_研发部_20260401_20260407.xlsx]
|
||
```
|
||
|
||
参数说明:
|
||
- `--users`(必填):逗号分隔的 userId 列表
|
||
- `--start`(必填):开始日期 `YYYY-MM-DD` 或 `YYYY-MM-DD HH:mm:ss`
|
||
- `--end`(必填):结束日期,同上
|
||
- `--out`(可选):输出文件名,不传则自动生成
|
||
- **没有 `--column-keywords`**,签到报表列固定
|
||
|
||
脚本内部自动处理:`attendance checkin records` 分批分段查询(每批 50 人,每段 7 天)→ `contact user get` 姓名/部门映射 → 时间戳转日期+时间 → 图片列展开(最多 9 张)→ 生成 Excel
|
||
|
||
> **注意**:签到接口时间限制为 7 天(不同于考勤报表的 32 天),脚本会自动按 7 天分段查询。
|
||
|
||
#### 脚本执行注意事项
|
||
|
||
- 脚本依赖 `openpyxl`,若未安装需先 `pip install openpyxl`
|
||
- 脚本摘要输出到 stdout,进度日志输出到 stderr
|
||
- 首次调试可加 `--inspect` 参数查看首条记录原始结构
|
||
- 脚本执行失败(exit ≠ 0)时,stderr 中有具体错误信息
|
||
|
||
### 阶段 4: 返回结果给用户
|
||
|
||
- 将脚本 stdout 输出的摘要信息原样转告用户
|
||
- 如果脚本输出 warning,原样转告用户
|
||
- 如果走的是默认月度汇总,追加:"已按月度汇总输出,如需明细/每日统计请告知"
|
||
- **不要把 Excel 内容贴在对话里**,只给路径和摘要
|
||
|
||
## 输出文件结构
|
||
|
||
### 月度汇总(双 sheet,自动生成)
|
||
|
||
`attendance_report_monthly.py` 输出的 Excel 文件包含 **2 个 sheet**:
|
||
|
||
| Sheet 名 | 布局 | 用途 |
|
||
|---------|------|------|
|
||
| `月度汇总` | 每人 1 行,列为基础信息 + 聚合字段 + 请假展开 + 考勤结果按天展开 | 整月数据汇总速览 |
|
||
| `日历表` | 每人 3 行(班次名称/考勤结果/工作时长),列为基础信息 + 指标 + 1日~N日 | 钉钉日历视图,逐日查看 |
|
||
|
||
**日历表结构示意**:
|
||
|
||
| 姓名 | 考勤组 | 部门 | 指标 | 1日 | 2日 | ... | 30日 |
|
||
|------|--------|------|------|------|------|------|------|
|
||
| 张三 | 研发组 | 技术部 | 班次名称 | 早班 | 早班 | ... | 休息 |
|
||
| | | | 考勤结果 | 正常 | 迟到 | ... | — |
|
||
| | | | 工作时长 | 8 | 7.5 | ... | 0 |
|
||
| 李四 | 研发组 | 技术部 | 班次名称 | 晚班 | 晚班 | ... | 早班 |
|
||
| ... | ... | ... | ... | ... | ... | ... | ... |
|
||
|
||
- 基础列(姓名/考勤组/部门)已纵向 3 行合并
|
||
- 日历表的 3 个指标字段(`班次名称`/`考勤结果`/`工作时长`)由脚本**强制**追加到 `report query-data` 查询字段中(即使用户的 `--column-keywords` 没包含),确保日历表非空
|
||
- 日历表数据来源与月度汇总相同(同一次 `report query-data` 调用),不会增加接口次数
|
||
|
||
## 预定义列集合
|
||
|
||
### 月度汇总(3 个基础信息列 + 18 个考勤数据列)
|
||
|
||
**基础信息列**(脚本自动从 `contact user get` 和原始记录中提取):
|
||
|
||
| 序号 | 字段名称 | 数据来源 |
|
||
|------|---------|---------|
|
||
| 1 | 姓名 | `contact user get --ids` |
|
||
| 2 | 考勤组 | `attendance group search` + `filtered-get --member` 反向映射 |
|
||
| 3 | 部门 | `contact user get --ids` |
|
||
|
||
**考勤数据列**(从 `report columns` 中按名称精确匹配):
|
||
|
||
| 序号 | 字段名称 |
|
||
|------|---------|
|
||
| 4 | 出勤天数 |
|
||
| 5 | 休息天数 |
|
||
| 6 | 工作时长 |
|
||
| 7 | 迟到次数 |
|
||
| 8 | 迟到时长 |
|
||
| 9 | 严重迟到次数 |
|
||
| 10 | 严重迟到时长 |
|
||
| 11 | 旷工迟到次数 |
|
||
| 12 | 早退次数 |
|
||
| 13 | 早退时长 |
|
||
| 14 | 上班缺卡次数 |
|
||
| 15 | 下班缺卡次数 |
|
||
| 16 | 旷工天数 |
|
||
| 17 | 出差时长 |
|
||
| 18 | 外出时长 |
|
||
| 19 | 请假(按假期类型展开为 4 列:`请假-事假`、`请假-调休`、`请假-病假`、`请假-年假`,值为月度求和;数据由脚本通过 `report query-leave` 单独查询) |
|
||
| 20 | 加班-审批单统计 |
|
||
| 21 | 考勤结果(按天展开为多列:1日/2日/.../31日,每列显示当天考勤状态) |
|
||
|
||
### 每日统计(4 个基础信息列 + 31 个考勤数据列)
|
||
|
||
**基础信息列**:
|
||
|
||
| 序号 | 字段名称 | 数据来源 |
|
||
|------|---------|---------|
|
||
| 1 | 姓名 | `contact user get --ids` |
|
||
| 2 | 考勤组 | `attendance group search` + `filtered-get --member` 反向映射 |
|
||
| 3 | 部门 | `contact user get --ids` |
|
||
| 4 | 日期 | 查询日期 |
|
||
|
||
**考勤数据列**:
|
||
|
||
| 序号 | 字段名称 |
|
||
|------|---------|
|
||
| 5 | 班次 |
|
||
| 6 | 上班1打卡时间 |
|
||
| 7 | 上班1打卡结果 |
|
||
| 8 | 下班1打卡时间 |
|
||
| 9 | 下班1打卡结果 |
|
||
| 10 | 上班2打卡时间 |
|
||
| 11 | 上班2打卡结果 |
|
||
| 12 | 下班2打卡时间 |
|
||
| 13 | 下班2打卡结果 |
|
||
| 14 | 上班3打卡时间 |
|
||
| 15 | 上班3打卡结果 |
|
||
| 16 | 下班3打卡时间 |
|
||
| 17 | 下班3打卡结果 |
|
||
| 18 | 关联的审批单 |
|
||
| 19 | 出勤天数 |
|
||
| 20 | 休息天数 |
|
||
| 21 | 工作时长 |
|
||
| 22 | 迟到次数 |
|
||
| 23 | 迟到时长 |
|
||
| 24 | 严重迟到次数 |
|
||
| 25 | 严重迟到时长 |
|
||
| 26 | 旷工迟到次数 |
|
||
| 27 | 早退次数 |
|
||
| 28 | 早退时长 |
|
||
| 29 | 上班缺卡次数 |
|
||
| 30 | 下班缺卡次数 |
|
||
| 31 | 旷工天数 |
|
||
| 32 | 出差时长 |
|
||
| 33 | 外出时长 |
|
||
| 34 | 请假(按假期类型展开为 4 列:`请假-事假`、`请假-调休`、`请假-病假`、`请假-年假`;数据由脚本通过 `report query-leave` 单独查询) |
|
||
| 35 | 加班-审批单统计 |
|
||
|
||
### 预设报表:加班报表
|
||
|
||
3 个基础信息列(姓名/考勤组/部门)+ 以下考勤数据列:
|
||
|
||
> 原始配置中的 TITLE_COLUMN(如"加班时长(转调休)")为分组标题,脚本不支持父子列结构,已打平为叶子字段。
|
||
|
||
| 序号 | 字段名称 | 说明 |
|
||
|------|---------|------|
|
||
| 4 | 加班-审批单统计 | — |
|
||
| 5 | 加班总时长 | — |
|
||
| 6 | 考勤结果 | 按天展开 |
|
||
|
||
**对应 `--column-keywords`**:`加班-审批单统计,加班总时长,考勤结果`
|
||
|
||
### 预设报表:请假报表
|
||
|
||
3 个基础信息列(姓名/考勤组/部门)+ 以下考勤数据列:
|
||
|
||
| 序号 | 字段名称 | 说明 |
|
||
|------|---------|------|
|
||
| 4 | 请假 | 按假期类型自动展开(事假/调休/病假/年假等),数据由脚本通过 `report query-leave` 单独查询 |
|
||
| 5 | 出差时长 | — |
|
||
| 6 | 外出时长 | — |
|
||
| 7 | 考勤结果 | 按天展开 |
|
||
|
||
**对应 `--column-keywords`**:`请假,出差时长,外出时长,考勤结果`
|
||
|
||
### 预设报表:异常报表
|
||
|
||
3 个基础信息列(姓名/考勤组/部门)+ 以下考勤数据列:
|
||
|
||
> 原始配置中的 TITLE_COLUMN(如"迟到"、"早退"、"缺卡")为分组标题,脚本不支持父子列结构,已打平为叶子字段。
|
||
|
||
| 序号 | 字段名称 | 说明 |
|
||
|------|---------|------|
|
||
| 4 | 迟到次数 | 原属分组「迟到」 |
|
||
| 5 | 迟到时长 | 同上 |
|
||
| 6 | 严重迟到次数 | 同上 |
|
||
| 7 | 严重迟到时长 | 同上 |
|
||
| 8 | 旷工迟到次数 | 同上 |
|
||
| 9 | 早退次数 | 原属分组「早退」 |
|
||
| 10 | 早退时长 | 同上 |
|
||
| 11 | 上班缺卡次数 | 原属分组「缺卡」 |
|
||
| 12 | 下班缺卡次数 | 同上 |
|
||
| 13 | 旷工天数 | — |
|
||
| 14 | 考勤结果 | 按天展开 |
|
||
|
||
**对应 `--column-keywords`**:`迟到次数,迟到时长,严重迟到次数,严重迟到时长,旷工迟到次数,早退次数,早退时长,上班缺卡次数,下班缺卡次数,旷工天数,考勤结果`
|
||
|
||
### 明细(3 个基础信息列 + 10 个打卡字段列)
|
||
|
||
**基础信息列**:
|
||
|
||
| 序号 | 字段名称 | 数据来源 |
|
||
|------|---------|---------|
|
||
| 1 | 姓名 | `contact user get --ids` |
|
||
| 2 | 考勤组 | `attendance group search` + `filtered-get --member` 反向映射 |
|
||
| 3 | 部门 | `contact user get --ids` |
|
||
|
||
**打卡字段列**(以打卡流水为主表,每条流水一行;通过打卡时间关联 `check result` 获取考勤时间和打卡结果):
|
||
|
||
| 序号 | 字段名称 | 数据来源 |
|
||
|------|---------|---------|
|
||
| 4 | 考勤日期 | `check record` |
|
||
| 5 | 考勤时间 | `check result`(班次规定的上/下班时间,按打卡时间关联) |
|
||
| 6 | 打卡时间 | `check record`(实际打卡时间) |
|
||
| 7 | 打卡结果 | `check result`(正常/迟到/早退/缺卡等,按打卡时间关联) |
|
||
| 8 | 打卡地址 | `check record` |
|
||
| 9 | 打卡备注 | `check record` |
|
||
| 10 | 异常打卡原因 | `check record` |
|
||
| 11 | 打卡图片 | `check record` |
|
||
| 12 | 打卡设备 | `check record` |
|
||
| 13 | 管理员修改备注 | `check record` |
|
||
|
||
### 签到报表(3 个基础信息列 + 11 个签到字段列 + 9 个图片列)
|
||
|
||
**基础信息列**:
|
||
|
||
| 序号 | 字段名称 | 数据来源 |
|
||
|------|---------|---------|
|
||
| 1 | 姓名 | `contact user get --ids` |
|
||
| 2 | 部门 | `contact user get --ids` |
|
||
| 3 | 完整部门 | `contact user get --ids` |
|
||
|
||
**签到字段列**(每条签到记录一行,数据来源均为 `attendance checkin records`):
|
||
|
||
| 序号 | 字段名称 | 数据来源 |
|
||
|------|---------|---------|
|
||
| 4 | 签到来源 | `checkinType` |
|
||
| 5 | 日期 | `timestamp`(毫秒时间戳转日期) |
|
||
| 6 | 时间 | `timestamp`(毫秒时间戳转时间) |
|
||
| 7 | 经度 | `longitude` |
|
||
| 8 | 纬度 | `latitude` |
|
||
| 9 | 地点 | `place` |
|
||
| 10 | 详细地址 | `detailPlace` |
|
||
| 11 | 拜访客户 | `customers` |
|
||
| 12 | 客户部门名称 | 预留(签到接口暂无此字段) |
|
||
| 13 | 工作内容 | `remark` |
|
||
| 14 | 手机标识 | `mobileId` |
|
||
|
||
**图片列**(从 `imageList` 数组展开,最多 9 列):
|
||
|
||
| 序号 | 字段名称 |
|
||
|------|---------|
|
||
| 15 | 图片1 |
|
||
| 16 | 图片2 |
|
||
| ... | ... |
|
||
| 23 | 图片9 |
|
||
|
||
## 分批查询规则(脚本内部自动处理)
|
||
|
||
| 维度 | 限制 | 脚本自动处理方式 |
|
||
|------|------|---------|
|
||
| 人数超限(月度/每日) | `query-data` 最多 20 人/次 | 自动按 5 人一批分批 |
|
||
| 人数超限(明细) | `check result` 最多 100 人/次 | 自动按 100 人一批分批 |
|
||
| 人数超限(签到) | `checkin records` 最多 100 人/次 | 自动按 50 人一批分批 |
|
||
| 时间超限(月度/每日) | `--start` 到 `--end` 不超过 32 天 | 自动按月分段 |
|
||
| 时间超限(明细) | `--start` 到 `--end` 不超过 1 个月 | 自动按月分段 |
|
||
| 时间超限(签到) | `--start` 到 `--end` 不超过 7 天 | 自动按 7 天分段 |
|
||
| 分页(明细打卡结果) | `check result` 单次最多 1000 条 | 自动翻页 |
|
||
|
||
## 错误处理
|
||
|
||
| 错误 | 原因 | 处理方式 |
|
||
|------|------|---------|
|
||
| 权限错误(403) | 当前账号非管理员 | 提示需要管理员权限,不要重试 |
|
||
| userId 无效 | 用户 ID 错误或已离职 | 脚本跳过并在摘要中标注 |
|
||
| 时间区间超长 | 接口可能性能不佳 | 提示"超过 1 年的数据建议分阶段导出" |
|
||
| openpyxl 未安装 | 环境缺包 | 输出 `pip install openpyxl` 安装提示 |
|
||
| 脚本执行失败 | 接口异常/配置问题 | 将 stderr 错误信息转告用户,可加 `--inspect` 重试 |
|
||
|
||
## 使用示例
|
||
|
||
### 示例 1: 团队月度汇总(默认)
|
||
**用户说**: "帮我生成研发组 4 月的考勤报表"
|
||
|
||
```bash
|
||
# 1. 获取部门成员
|
||
dws contact dept search --query "研发组" --format json
|
||
dws contact dept list-members --ids <deptId> --format json
|
||
|
||
# 2. 调用脚本(默认月度汇总,不传 --column-keywords)
|
||
python scripts/attendance_report_monthly.py \
|
||
--users userId1,userId2,... \
|
||
--start "2026-04-01" --end "2026-04-30"
|
||
```
|
||
|
||
### 示例 2: 加班报表(预设)
|
||
**用户说**: "帮我出一份研发组 4 月的加班报表"
|
||
|
||
```bash
|
||
python scripts/attendance_report_monthly.py \
|
||
--users userId1,userId2,... \
|
||
--start "2026-04-01" --end "2026-04-30" \
|
||
--column-keywords "加班-审批单统计,加班总时长,考勤结果"
|
||
```
|
||
|
||
### 示例 3: 请假报表(预设)
|
||
**用户说**: "帮我导出研发组 4 月的请假出差情况"
|
||
|
||
```bash
|
||
python scripts/attendance_report_monthly.py \
|
||
--users userId1,userId2,... \
|
||
--start "2026-04-01" --end "2026-04-30" \
|
||
--column-keywords "请假,出差时长,外出时长,考勤结果"
|
||
```
|
||
|
||
### 示例 4: 异常报表(预设)
|
||
**用户说**: "帮我出研发组 4 月的异常考勤报表"
|
||
|
||
```bash
|
||
python scripts/attendance_report_monthly.py \
|
||
--users userId1,userId2,... \
|
||
--start "2026-04-01" --end "2026-04-30" \
|
||
--column-keywords "迟到次数,迟到时长,严重迟到次数,严重迟到时长,旷工迟到次数,早退次数,早退时长,上班缺卡次数,下班缺卡次数,旷工天数,考勤结果"
|
||
```
|
||
|
||
### 示例 5: 自定义维度筛选
|
||
**用户说**: "帮我出一份研发组 4 月的工作时长报表"
|
||
|
||
```bash
|
||
python scripts/attendance_report_monthly.py \
|
||
--users userId1,userId2,... \
|
||
--start "2026-04-01" --end "2026-04-30" \
|
||
--column-keywords "工作时长"
|
||
```
|
||
|
||
### 示例 6: 每日统计
|
||
**用户说**: "帮我出一份研发组 4 月每天的出勤情况"
|
||
|
||
```bash
|
||
python scripts/attendance_report_daily.py \
|
||
--users userId1,userId2,... \
|
||
--start "2026-04-01" --end "2026-04-30"
|
||
```
|
||
|
||
### 示例 7: 明细报表
|
||
**用户说**: "帮我导出研发组 4 月的考勤明细"
|
||
|
||
```bash
|
||
python scripts/attendance_report_detail.py \
|
||
--users userId1,userId2,... \
|
||
--start "2026-04-01" --end "2026-04-30"
|
||
```
|
||
|
||
### 示例 8: 请假记录
|
||
**用户说**: "帮我导出研发组 4 月的请假记录"
|
||
|
||
```bash
|
||
python scripts/attendance_report_record.py \
|
||
--type leave \
|
||
--users userId1,userId2,... \
|
||
--start "2026-04-01" --end "2026-04-30"
|
||
```
|
||
|
||
### 示例 9: 出差记录
|
||
**用户说**: "帮我导出研发组 4 月的出差记录"
|
||
|
||
```bash
|
||
python scripts/attendance_report_record.py \
|
||
--type trip \
|
||
--users userId1,userId2,... \
|
||
--start "2026-04-01" --end "2026-04-30"
|
||
```
|
||
|
||
### 示例 10: 补卡记录
|
||
**用户说**: "帮我导出研发组 5 月的补卡记录"
|
||
|
||
```bash
|
||
python scripts/attendance_report_record.py \
|
||
--type patch \
|
||
--users userId1,userId2,... \
|
||
--start "2026-05-01" --end "2026-05-31"
|
||
```
|
||
|
||
### 示例 11: 签到报表
|
||
**用户说**: "帮我导出研发组上周的签到记录"
|
||
|
||
```bash
|
||
python scripts/attendance_report_checkin.py \
|
||
--users userId1,userId2,... \
|
||
--start "2026-05-26" --end "2026-06-01"
|
||
```
|
||
|
||
## 配套脚本
|
||
|
||
| 脚本 | 报表类型 | 数据来源 | CLI 参数 |
|
||
|------|---------|---------|---------|
|
||
| [attendance_report_detail.py](../scripts/attendance_report_detail.py) | 明细 | `check result` + `check record` | `--users --start --end [--out]` |
|
||
| [attendance_report_monthly.py](../scripts/attendance_report_monthly.py) | 月度汇总(默认) | `report columns` + `report query-data` | `--users --start --end [--column-keywords] [--out]` |
|
||
| [attendance_report_daily.py](../scripts/attendance_report_daily.py) | 每日统计 | `report columns` + `report query-data` | `--users --start --end [--column-keywords] [--out]` |
|
||
| [attendance_report_record.py](../scripts/attendance_report_record.py) | 考勤记录 | `attendance approve list` + `oa approval detail` | `--type --users --start --end [--out]` |
|
||
| [attendance_report_checkin.py](../scripts/attendance_report_checkin.py) | 签到报表 | `attendance checkin records` | `--users --start --end [--out]` |
|
||
| [attendance_report_common.py](../scripts/attendance_report_common.py) | 公共模块(不可单独执行) | — | — |
|