Files
xh-medical-sign-web/clinical-web/docs/reports-api.md
T

224 lines
12 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.
# 报表分析模块接口核验与后端接口需求
> 核验基准:MEDISIGN 患者电子签 API 文档([https://ipad.shenynet.com/doc.html#/home](https://ipad.shenynet.com/doc.html#/home))。
>
> 本次核验时间:2026-09-01。接口文档当前为 v1,未提供独立的“报表分析”接口分组。
## 1. 核验结论
当前报表页面可以使用现有签署任务、模板和组织接口完成基础展示,但后端暂时没有报表聚合能力。页面真实模式目前采用以下临时方案:
1. 查询当前用户有权查看的全部签署任务;
2. 按接口允许的最大页大小 200 条循环请求所有分页;
3. 使用模板接口补充文档名称和类别;
4. 使用院区、科室接口补充筛选字典;
5. 在前端按业务时间范围聚合指标、趋势和科室分布。
这个方案适合联调和小数据量验证,不适合作为长期报表架构。任务量增大后,首次打开页面会产生多次请求并占用浏览器内存;而且当前任务列表只支持按 `createdAt` 查询,无法让后端直接按签署完成时间或过期时间聚合。
## 2. 当前已接入接口
| 页面功能 | 接口 | 状态 | 说明 |
| -------------- | ------------------------------------------ | ------ | -------------------------------------------------------------------------------------------------- |
| 签署任务明细 | `GET /api/v1/sign-tasks` | 已接入 | 读取所有可见分页,使用 `page`、`size`,最大页大小为 200 |
| 任务状态 | `GET /api/v1/sign-tasks` | 已接入 | 使用 `CREATED`、`WAITING_SIGN`、`GENERATING`、`SIGNED`、`EXPIRED`、`VOIDED`、`FAILED` 映射页面状态 |
| 任务时间 | `GET /api/v1/sign-tasks` | 已接入 | 使用 `createdAt`、`signedAt`、`expiredAt` |
| 文档名称和类别 | `GET /api/v1/templates/available-versions` | 已接入 | 用 `templateVersionId` 关联模板版本;历史模板不可见时只能降级显示 |
| 院区筛选 | `GET /api/v1/campuses` | 已接入 | 动态生成院区选项,并用 `campusId` 映射任务院区 |
| 科室筛选 | `GET /api/v1/departments` | 已接入 | 动态生成科室选项;任务中出现的科室也会补入选项 |
| 明细查看 | 工作台任务详情路由 | 已接入 | 点击明细跳转签署工作台,由工作台查询任务详情和签署文件 |
| 当前筛选导出 | 浏览器生成 CSV | 已接入 | 导出当前已加载且按创建时间筛选的任务;不是后端审计型导出 |
`GET /api/v1/sign-tasks` 当前文档明确支持的筛选字段包括:
- `page`、`size`;
- `keyword`、`patientId`、`visitId`、`templateVersionId`;
- `status`、`signMethod`、`campusId`、`departmentId`;
- `createdFrom`、`createdTo`。
响应中已经提供报表所需的基础字段:任务状态、签署方式、患者和就诊脱敏快照、院区/科室 ID、`signedAt`、`expiredAt`、`createdAt` 和 `updatedAt`。文档没有提供独立的聚合统计响应,也没有提供签署耗时字段。
## 3. 本轮前端修复
- 删除了原先指向不存在的 `/management/reports/overview` 的报表 API;统一通过 `src/api/management/reports.ts` 聚合真实接口。
- 修复只读取第 1 页、最多 200 条导致的统计和导出不完整问题。
- 每日趋势改为按 `signedAt` 统计,不再按任务创建时间冒充签署完成时间。
- “签署完成”按本期 `signedAt` 统计;“累计发起任务”和明细仍按本期 `createdAt` 统计。
- “按时签署率”只统计有签署/过期时间的终态任务,并以 `signedAt <= expiredAt` 判断签署是否按时;`VOIDED`、`FAILED` 和未完成任务不进入分母。
- 平均用时不再默认填充 7 分钟;当前按 `signedAt - createdAt` 计算任务完成耗时,没有可用数据时显示 `—`。
- `month` 趋势按当月实际天数生成;`custom` 增加起止日期并校验起始日期不能晚于结束日期。
- `FAILED` 单独显示为“处理失败”,不再错误归类为“已作废”。
- 导出增加签署完成时间和过期时间,文件名使用本地日期,且导出内容覆盖全部已加载分页。
- 任务院区优先使用 `campusId` 对应的组织字典,避免字典顺序或默认值导致院区误归类。
## 4. 当前前端统计口径
当前临时聚合的时间范围使用医院浏览器本地时间。生产环境建议由后端统一按 `Asia/Shanghai` 计算。
### 4.1 指标卡
- `累计发起任务`:`createdAt` 在当前日期范围内,且符合院区、科室、文档类别筛选的任务数。
- `签署完成`:`status=SIGNED` 且 `signedAt` 在当前日期范围内的任务数。
- `按时签署率`:本期已签署任务与本期已超时任务作为终态样本;分子为 `signedAt <= expiredAt` 的已签署任务,分母为两类终态任务之和。
- `平均签署用时`:当前使用 `signedAt - createdAt` 的平均分钟数。该值是“任务从创建到完成的总耗时”,不是患者实际落笔时长。
### 4.2 趋势和科室分布
- 每日趋势按 `SIGNED` 任务的 `signedAt` 按自然日统计。
- 科室分布按本期完成签署的任务、使用任务科室名称统计。
- 明细表按 `createdAt` 筛选,便于核对本期发起的任务;这意味着明细条数与“本期签署完成”可能不完全相等,后端聚合接口上线后建议在界面上明确两个时间维度。
## 5. 后端缺口与推荐接口
### 5.1 签署报表聚合接口(最高优先级)
建议新增:
```http
GET /api/v1/reports/signing/overview
X-Token: {登录令牌}
```
建议请求参数:
| 参数 | 类型 | 必填 | 说明 |
| --------------------------- | ------------- | ---- | ------------------------------------------------ |
| `createdFrom` / `createdTo` | ISO-8601 | 否 | 发起任务统计和明细的时间范围 |
| `signedFrom` / `signedTo` | ISO-8601 | 否 | 签署完成、趋势和完成分布的时间范围 |
| `expiredFrom` / `expiredTo` | ISO-8601 | 否 | 超时任务统计的时间范围 |
| `campusId` | UUID | 否 | 院区筛选;不传表示当前权限范围内全部院区 |
| `departmentId` | UUID | 否 | 科室筛选 |
| `category` | string | 否 | 文档类别,建议使用模板的稳定分类编码 |
| `signMethod` | `PAD` / `SMS` | 否 | 签署方式筛选 |
| `timezone` | string | 否 | 默认 `Asia/Shanghai`;建议服务端固定或校验白名单 |
| `detailPage` / `detailSize` | integer | 否 | 明细分页,`detailSize` 最大 200 |
建议响应:
```json
{
"code": 0,
"message": "OK",
"data": {
"timezone": "Asia/Shanghai",
"metrics": {
"initiatedCount": 128,
"signedCount": 112,
"onTimeSignedCount": 108,
"onTimeDenominator": 120,
"onTimeRate": 90.0,
"averageCompletionDurationSeconds": 382,
"durationSampleCount": 112
},
"trend": [
{
"date": "2026-09-01",
"signedCount": 32
}
],
"departments": [
{
"departmentId": "科室 UUID",
"departmentName": "消化内科",
"initiatedCount": 40,
"signedCount": 36,
"onTimeSignedCount": 35,
"onTimeRate": 87.5
}
],
"details": {
"records": [],
"page": 1,
"size": 200,
"total": 128,
"pages": 1
}
},
"traceId": "链路追踪 ID",
"timestamp": "2026-09-01T08:00:00Z"
}
```
后端应在 SQL 聚合前执行当前用户的数据范围、模板 ACL 和院区/科室权限过滤,不能让前端拉取无权数据后再过滤。`onTimeRate` 的分母、是否排除作废任务、过期任务的口径需要在接口契约中固定,不能由不同页面各自猜测。
### 5.2 稳定的模板快照信息
当前任务响应只有 `templateVersionId` 和模板版本信息;如果模板不再处于当前用户可见的可用版本列表,报表无法可靠获取名称和类别,只能显示版本号或根据文档名称猜测分类。
建议在签署任务响应中增加不可变的模板快照摘要,或由报表接口直接返回:
```json
{
"templateId": "模板 UUID",
"templateVersionId": "模板版本 UUID",
"templateName": "胃镜检查知情同意书",
"templateCategory": "EXAM_CONSENT"
}
```
分类应使用稳定编码和展示字典,不建议前端继续通过“入院”“告知”等中文名称关键词推断。
### 5.3 可审计的签署耗时字段
`createdAt` 到 `signedAt` 只能表示任务生命周期耗时,短信等待和患者未操作时间会被计入。若产品要展示真正的签署用时,建议返回:
```json
{
"signStartedAt": "2026-09-01T07:53:00Z",
"signedAt": "2026-09-01T08:00:02Z",
"signDurationSeconds": 422
}
```
其中 `signStartedAt` 应来自签署投递/签署事件,而不是前端打开页面时自行记录。聚合接口应同时返回有效样本数;没有有效耗时样本时返回 `null`,前端显示 `—`。
### 5.4 后端导出接口
当前 CSV 是浏览器导出,只适合已加载的少量明细,不能替代正式导出。建议提供异步导出:
```http
POST /api/v1/reports/signing/export-jobs
GET /api/v1/reports/signing/export-jobs/{jobId}
GET /api/v1/reports/signing/export-jobs/{jobId}/download
```
导出任务请求复用报表筛选条件,响应返回任务状态、文件有效期和下载地址。导出的每一行都应在服务端按权限过滤,并记录操作人、筛选条件摘要、生成时间、文件过期时间和 `traceId`。文件中只返回当前角色允许查看的脱敏患者字段,不应包含明文身份证号、手机号或完整病历。
### 5.5 时间范围查询能力(没有聚合接口时的最低要求)
如果近期无法提供聚合接口,至少请扩展 `GET /api/v1/sign-tasks`:
- 增加 `signedFrom`、`signedTo`;
- 增加 `expiredFrom`、`expiredTo`;
- 明确多个状态、时间条件的组合语义;
- 保证 `total`、`page`、`size`、`pages` 在权限过滤后保持一致;
- 保证分页排序稳定,例如按 `createdAt DESC, id DESC`;
- 如需前端核对总量,提供按条件返回的汇总字段,避免客户端循环读取全部历史任务。
## 6. 权限、错误和审计要求
推荐复用现有统一响应包和错误约定:
| HTTP 状态 | 场景 |
| --------- | ------------------------------------- |
| `200` | 查询或导出任务创建成功 |
| `400` | 日期格式、范围、分页或筛选参数错误 |
| `401` | 未登录或令牌失效 |
| `403` | 无报表查询权限或超出院区/科室数据范围 |
| `404` | 导出任务不存在或已过期 |
| `409` | 导出条件版本或数据快照冲突 |
| `429` | 导出任务频率超限 |
| `500` | 服务端聚合或文件生成异常 |
报表查询、导出和下载都应记录审计信息;审计内容记录筛选条件摘要即可,不要记录明文患者证件号、手机号、签名原图或完整病历内容。
## 7. 前端联调验收标准
- 院区、科室、文档类别和签署方式筛选只返回当前用户有权查看的数据。
- 趋势按 `signedAt` 统计;任务延迟签署时不会落入创建日。
- 超时按 `expiredAt` 统计;跨自然日时按 `Asia/Shanghai` 计算。
- 签署耗时没有有效样本时返回空值并显示 `—`,不使用固定默认值。
- 明细支持服务端分页;导出结果不受浏览器已加载条数限制。
- 同一筛选条件的指标、趋势、科室汇总和明细使用明确且一致的时间口径。
- 返回 `traceId`,前端错误提示可以关联后端日志排查。