safety-eval-service/docs/机构端首页驾驶舱接口设计.md

106 lines
8.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 机构端首页(驾驶舱)接口设计
> 对应前端路由:`/container/driver?pageMode=3` → 机构端首页 `Institution/Dashboard`
> 基址:`/safetyEval/institution/dashboard`
> 全部为**新增**聚合接口,落在 `InstitutionDashboardController`,未改动任何既有功能/接口。
> 实现位置:`safety-eval-client/.../co/institution/dashboard/*CO`、`.../api/institution/InstitutionDashboardApi`、`safety-eval-adapter/.../web/institution/InstitutionDashboardController`、`safety-eval-app/.../executor/institution/InstitutionDashboardExecutor`
## 1. 页面动态数据项 → 接口映射
| 大屏板块 | 动态项 | 对应接口 |
|---|---|---|
| 当前项目节点统计 | 项目总数 / 法定项目 + 8 节点待办 + 已归档 + 项目延期 | `GET /project-node-stats` |
| 通知提醒 | 资质现场审查通知 / 监督检查通知 / 未读监管通知 | `GET /notices` |
| 服务行业项目统计 | 各行业「项目数 / 法定项目数」 | `GET /industry-stat` |
| 评价类别占比 | 各评价类别项目数 + 总数 | `GET /eval-type-ratio` |
| 项目执行情况 | 项目列表(编号/名称/被评价企业/类别/负责人/结束日期) | `GET /project-execution` |
## 2. 公共约定
- 鉴权:`orgId` 取自 `ThreadLocalUserInfoAdapter`(机构端请求上下文,由网关/拦截器注入)。若取不到 `orgId`,所有接口返回空数据(不报错),便于未登录/非机构场景降级。
- 聚合策略:复用既有 `EvalProjectGateway.page()`、`EvalProjectNodeOverviewAssembler.buildForInstitution()`、`SafetyMessageGateway.page()`、`EvalCustomerGateway.get()`,在内存做聚合,**不新写脆弱 SQL**,避免 N+1 与跨库耦合。
- 性能:建议前端对 5 个接口加 30~60s 短 TTL 缓存;面板级相互独立,单接口异常不影响其余面板。
- 响应:`SingleResponse<CO>`,成功 `code="0"`
## 3. 接口清单
### 3.1 GET /project-node-stats — 当前项目节点统计
- **入参**:无
- **出参** `InstitutionDashboardProjectNodeStatsCO`
- `totalProjects` 项目总数
- `statutoryProjects` 法定项目数
- `nodeStats[]``nodeCode`(NODE_01..NODE_08)、`nodeName`(待X)、`pendingCount`(待办数)
- `archivedProjectCount` 已归档项目数
- `delayedProjectCount` 项目延期数
- **边界**仅统计当前机构orgId名下项目节点待办口径 = 节点状态为「未开始」(与监管端 `processOverview` 一致)。
- **数据源**`eval_project`orgId 过滤)、`EvalProjectNodeOverviewAssembler.buildForInstitution(projectId)`(节点状态)、`EvalProjectGateway.countByOrgIdAndProgressStatus(orgId,"DELAY")`(延期)。
- **业务逻辑**
1. `listOrgProjects(orgId)` 取本机构全部项目;
2. 总数 / 法定项目(`is_statutory=1`)计数;
3. 逐项目 `buildForInstitution` 取 8 节点,状态为「未开始」则该节点 `pendingCount+1`(单项目装配异常 try-catch 跳过,保证整体可用);
4. `archiveFlag=1` 计已归档;`progressStatus=DELAY` 计延期。
### 3.2 GET /notices — 通知提醒
- **入参**:无
- **出参** `InstitutionDashboardNoticeCO`
- `qualOnSiteReviewCount` 资质现场审查通知数(`sendType=ON_SITE_REVIEW_NOTICE`
- `inspectionCount` 监督检查通知数(`sendType=INSP_NOTICE_ORG`
- `unreadRegulatoryCount` 未读监管通知数(本机构消息中 `sendState!=1`
- **边界**:仅统计本机构消息;未读 = `sendState` 非 1已读标记 `MessageSendStateEnum.SENT=1`)。
- **数据源**`safety_message``SafetyMessageGateway.page`,按 orgId + sendType 统计总数;按 orgId 取列表过滤未读)。
- **业务逻辑**
1.`orgId + sendType=ON_SITE_REVIEW_NOTICE``total`
2.`orgId + sendType=INSP_NOTICE_ORG``total`
3.`orgId` 取消息列表,统计 `sendState!=1` 的数量(消息量较大时受 `PAGE_SIZE=1000` 限制,机构维度一般远小于此值)。
### 3.3 GET /industry-stat — 服务行业项目统计
- **入参**:无
- **出参** `InstitutionDashboardIndustryStatCO`
- `list[]``industryCode`、`industryName`、`projectCount`、`statutoryProjectCount`
- **边界**:仅返回「有项目」的行业(前端按固定类目轴渲染,缺失类目补 0行业名称取自 `IndustryEnum`
- **数据源**`eval_project`orgId 过滤),按 `industry_code` 分组,法定项目按 `is_statutory=1` 再计。
- **业务逻辑**`listOrgProjects` → `groupBy(industryCode)` → 每组计项目数 / 法定项目数,名称用 `IndustryEnum.ofCode(code).value`
### 3.4 GET /eval-type-ratio — 评价类别占比
- **入参**:无
- **出参** `InstitutionDashboardEvalTypeRatioCO`
- `totalProjectCount` 项目总数
- `items[]``evalTypeCode`、`evalTypeName`、`count`
- **边界**:仅本机构;评价类型名称取自 `EvalTypeEnum`PRE 安全预评价 / ACCEPT 安全设施竣工验收评价 / STATUS 安全现状评价)。
- **数据源**`eval_project`orgId 过滤),按 `eval_type_code` 分组。
- **业务逻辑**`listOrgProjects` → `groupBy(evalTypeCode)` → 计各组数量与总和,名称用 `EvalTypeEnum.ofCode(code).value`
### 3.5 GET /project-execution — 项目执行情况
- **入参**`limit`(可选,默认 10范围 1~50
- **出参** `InstitutionDashboardProjectExecutionCO`
- `list[]``projectId`、`projectNo`(项目编号)、`projectName`、`customerName`(被评价企业)、`evalTypeCode`、`evalTypeName`、`projectLeaderName`(项目负责人)、`planEndDate`(yyyy-MM-dd)
- **边界**:仅本机构;按 `planEndDate` 升序取前 `limit` 条(最近到期在前,空日期置尾);被评价企业名称经 `EvalCustomerGateway.get(customerId)` 解析(解析失败置空,不影响其余行)。
- **数据源**`eval_project`orgId 过滤)、`eval_customer``EvalCustomerGateway.get`)。
- **业务逻辑**`listOrgProjects` → 按 `planEndDate` 升序 → `take(limit)` → 逐行映射,评价类别名称用 `EvalTypeEnum`,被评价企业名称查客户表。
## 4. 已知缺口 / 口径说明
1. **行业类目不一致**:前端 `mockData.js` 硬编码 7 个行业(危险化学品/非煤矿山/金属冶炼/工贸/烟花爆竹/石油天然气/其他行业),与数据库 `IndustryEnum`COAL_MINING 煤炭开采业… 等 8 类)**不一致**。本接口返回 `IndustryEnum` 真实编码/名称,前端需以其固定类目轴对齐合并(缺失补 0
2. **评价类别名称**:前端写「安全验收评价」,实际 `EvalTypeEnum.ACCEPT` 为「安全设施竣工验收评价」,按枚举真实值返回。
3. **消息未读口径**`safety_message.send_state` 仅 0/1未读/已读);`unreadRegulatoryCount` 统计 `sendState!=1`,即本机构全部未读监管消息(含资质现场审查、监督检查、报告抽查等)。
4. **节点待办口径**:与监管端一致,待办 = 节点状态「未开始」。处于「进行中/退回」的节点不计入待办(计入已到达)。
5. **项目延期**:直接复用 `EvalProjectGateway.countByOrgIdAndProgressStatus(orgId,"DELAY")`,与系统既有延期判定一致。
6. **未做写操作**:本批接口均为只读聚合,不改写任何表。
## 5. 文件清单(均为新增)
- `safety-eval-client/.../co/institution/dashboard/InstitutionDashboardProjectNodeStatsCO.java`
- `safety-eval-client/.../co/institution/dashboard/InstitutionDashboardNoticeCO.java`
- `safety-eval-client/.../co/institution/dashboard/InstitutionDashboardIndustryStatCO.java`
- `safety-eval-client/.../co/institution/dashboard/InstitutionDashboardEvalTypeRatioCO.java`
- `safety-eval-client/.../co/institution/dashboard/InstitutionDashboardProjectExecutionCO.java`
- `safety-eval-client/.../api/institution/InstitutionDashboardApi.java`
- `safety-eval-adapter/.../web/institution/InstitutionDashboardController.java`
- `safety-eval-app/.../executor/institution/InstitutionDashboardExecutor.kt`
- `docs/openapi/机构端-首页驾驶舱.openapi.yaml`