Compare commits
2 Commits
407d3c00e4
...
b1595c3b8f
| Author | SHA1 | Date |
|---|---|---|
|
|
b1595c3b8f | |
|
|
5c7d3fb0fc |
|
|
@ -0,0 +1,13 @@
|
|||
-- 机构端报告库原型字段补齐(eval_report)
|
||||
-- 若表已存在,执行本增量脚本
|
||||
-- 日期:2026-07-23
|
||||
|
||||
ALTER TABLE `eval_report`
|
||||
ADD COLUMN `industry_code` varchar(32) DEFAULT NULL COMMENT '所属行业编码' AFTER `eval_type_name`,
|
||||
ADD COLUMN `industry_name` varchar(50) DEFAULT NULL COMMENT '所属行业名称(危化/矿山/冶炼/工贸等)' AFTER `industry_code`,
|
||||
ADD COLUMN `evaluated_unit_name` varchar(200) DEFAULT NULL COMMENT '被评价单位名称' AFTER `customer_id`,
|
||||
ADD COLUMN `issue_date` date DEFAULT NULL COMMENT '报告签发日期' AFTER `archive_time`,
|
||||
ADD COLUMN `page_count` int DEFAULT NULL COMMENT '报告页数' AFTER `issue_date`,
|
||||
ADD COLUMN `secret_level_code` varchar(32) DEFAULT NULL COMMENT '保密属性编码(NORMAL/TRADE_SECRET/PRIVACY/CLASSIFIED)' AFTER `page_count`,
|
||||
ADD COLUMN `secret_level_name` varchar(50) DEFAULT NULL COMMENT '保密属性名称' AFTER `secret_level_code`,
|
||||
ADD COLUMN `submit_flag` tinyint DEFAULT 2 COMMENT '是否已报送监管(1是2否)' AFTER `complete_flag`;
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
-- 监督检查告知:对齐原型筛选/展示(来源预警编号、告知附件)
|
||||
-- 状态扩展:0待下发;来源扩展:4风险预警(业务码,无需改列类型)
|
||||
|
||||
ALTER TABLE `insp_notice`
|
||||
ADD COLUMN `source_ref_no` varchar(64) DEFAULT NULL COMMENT '来源预警/业务编号(如W-PROJ-2026-009)' AFTER `source_ref_id`,
|
||||
ADD COLUMN `notice_urls` varchar(2000) DEFAULT NULL COMMENT '告知附件URL,逗号分隔' AFTER `notice_content`;
|
||||
|
||||
ALTER TABLE `insp_notice`
|
||||
MODIFY COLUMN `source_type_code` int DEFAULT NULL COMMENT '来源方式编码(1年度计划2专项安排3其他4风险预警)',
|
||||
MODIFY COLUMN `status_code` int DEFAULT NULL COMMENT '状态编码(0待下发1已下发2已确认3已反馈4已办结)',
|
||||
MODIFY COLUMN `result_code` int DEFAULT NULL COMMENT '检查结果编码(1未发现问题/合格2责令整改/不合格3转入风险预警/限期整改)';
|
||||
|
|
@ -21,19 +21,27 @@ create table `eval_report` (
|
|||
`org_id` bigint not null comment '机构id',
|
||||
`project_id` bigint default null comment '关联项目id(可空,历史报告)',
|
||||
`customer_id` bigint default null comment '客户id',
|
||||
`evaluated_unit_name` varchar(200) default null comment '被评价单位名称',
|
||||
`report_no` varchar(64) default null comment '报告编号',
|
||||
`report_name` varchar(200) not null comment '报告名称',
|
||||
`report_year` int default null comment '报告年度',
|
||||
`eval_type_code` varchar(32) default null comment '评价类型编码(PRE安全预评价 ACCEPT安全验收评价 STATUS安全现状评价)',
|
||||
`eval_type_name` varchar(50) default null comment '评价类型名称(安全预评价/安全验收评价/安全现状评价)',
|
||||
`industry_code` varchar(32) default null comment '所属行业编码',
|
||||
`industry_name` varchar(50) default null comment '所属行业名称',
|
||||
`business_scope` varchar(500) default null comment '业务范围',
|
||||
`file_url` varchar(500) default null comment '主文件地址',
|
||||
`file_name` varchar(200) default null comment '主文件名',
|
||||
`public_flag` tinyint default 2 comment '是否公开(1是2否)',
|
||||
`complete_flag` tinyint default null comment '资料是否完整(1是2否)',
|
||||
`submit_flag` tinyint default 2 comment '是否已报送监管(1是2否)',
|
||||
`report_status_code` int default null comment '报告状态编码(1已入库2抽查中3待整改4已复核)',
|
||||
`report_status_name` varchar(50) default null comment '报告状态名称',
|
||||
`archive_time` datetime default null comment '入库时间',
|
||||
`issue_date` date default null comment '报告签发日期',
|
||||
`page_count` int default null comment '报告页数',
|
||||
`secret_level_code` varchar(32) default null comment '保密属性编码',
|
||||
`secret_level_name` varchar(50) default null comment '保密属性名称',
|
||||
`delete_enum` varchar(32) default null comment '删除标识true false',
|
||||
`remarks` varchar(255) default null comment '备注',
|
||||
`create_name` varchar(50) default null comment '创建人姓名',
|
||||
|
|
@ -120,19 +128,21 @@ create table `insp_notice` (
|
|||
`notice_no` varchar(64) not null comment '告知编号',
|
||||
`insp_type_code` varchar(32) default null comment '检查类型编码(PROJECT_PROCESS项目过程检查 QUAL_KEEP资质保持检查 SPECIAL专项检查)',
|
||||
`insp_type_name` varchar(50) default null comment '检查类型名称(项目过程检查/资质保持检查/专项检查)',
|
||||
`source_type_code` int default null comment '来源方式编码(1年度计划2专项安排3其他)',
|
||||
`source_type_code` int default null comment '来源方式编码(1年度计划2专项安排3其他4风险预警)',
|
||||
`source_type_name` varchar(50) default null comment '来源方式名称',
|
||||
`source_ref_id` bigint default null comment '来源业务id(可选)',
|
||||
`source_ref_no` varchar(64) default null comment '来源预警/业务编号(如W-PROJ-2026-009)',
|
||||
`project_id` bigint default null comment '关联项目id',
|
||||
`plan_insp_time` datetime default null comment '计划检查时间',
|
||||
`leader_name` varchar(50) default null comment '检查组长',
|
||||
`notice_content` varchar(2000) default null comment '告知内容',
|
||||
`status_code` int default null comment '状态编码(1已下发2已确认3已反馈4已办结)',
|
||||
`notice_urls` varchar(2000) default null comment '告知附件URL,逗号分隔',
|
||||
`status_code` int default null comment '状态编码(0待下发1已下发2已确认3已反馈4已办结)',
|
||||
`status_name` varchar(50) default null comment '状态名称',
|
||||
`confirm_flag` tinyint default 2 comment '机构是否确认(1是2否)',
|
||||
`confirm_time` datetime default null comment '确认时间',
|
||||
`send_time` datetime default null comment '下发时间',
|
||||
`result_code` int default null comment '检查结果编码(1合格2不合格3限期整改)',
|
||||
`result_code` int default null comment '检查结果编码(1未发现问题/合格2责令整改/不合格3转入风险预警/限期整改)',
|
||||
`result_name` varchar(50) default null comment '检查结果名称',
|
||||
`result_content` varchar(2000) default null comment '结果说明',
|
||||
`result_urls` varchar(2000) default null comment '结果附件',
|
||||
|
|
|
|||
|
|
@ -30,22 +30,30 @@ flowchart TB
|
|||
POST_GBS_LINK --> GBS_ROLE_REF
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## 2. 硬性约束
|
||||
|
||||
1. **存在硬编码角色权限的业务逻辑时**,必须先在 GBS 创建对应角色,再在本系统 `GbsRoleEnum` 中登记;业务代码只从枚举取值,禁止散落硬编码角色码字符串。
|
||||
2. **业务系统通过岗位与 GBS 角色关联**;当岗位重新分配 GBS 角色、岗位编辑且已有 GBS 角色关联且岗位下存在人员、或人员岗位发生变更且新岗位已关联 GBS 角色时,触发对人员 GBS 角色的更新(覆盖式 `updateUserRole`)。
|
||||
3. GBS `UserFacade` **当前无批量改角色接口**,实现上优先探测批量能力;若无则 **依次** 调用 `gbsUserFacadeClient.updateUserRole`(封装为 `updateUserRolesSequentially`)。
|
||||
|
||||
|
||||
|
||||
## 3. 数据模型
|
||||
|
||||
表 `org_position` 新增字段:
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `gbs_role_id` | bigint | 关联 GBS 角色ID |
|
||||
| `gbs_role_code` | varchar(64) | 关联 GBS 角色编码 |
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
| --------------- | ------------ | ---------------- |
|
||||
| `gbs_role_id` | bigint | 关联 GBS 角色ID |
|
||||
| `gbs_role_code` | varchar(64) | 关联 GBS 角色编码 |
|
||||
| `gbs_role_name` | varchar(100) | 关联 GBS 角色名称(展示用) |
|
||||
|
||||
|
||||
MySQL(全量):
|
||||
|
||||
```sql
|
||||
|
|
@ -61,16 +69,20 @@ ALTER TABLE `org_position`
|
|||
|
||||
## 4. 接口
|
||||
|
||||
| 方法 | 路径 | 说明 |
|
||||
|------|------|------|
|
||||
| POST | `/safetyEval/org-position/assign-gbs-role` | 为岗位分配 GBS 角色,并同步岗位下人员 |
|
||||
| GET | `/safetyEval/org-position/gbs-roles` | 拉取 GBS 角色列表(下拉) |
|
||||
| POST | `/safetyEval/org-position/modify` | 原编辑接口;若岗位已有 GBS 角色且有人员,则同步人员角色 |
|
||||
|
||||
| 方法 | 路径 | 说明 |
|
||||
| ---- | ------------------------------------------ | ------------------------------ |
|
||||
| POST | `/safetyEval/org-position/assign-gbs-role` | 为岗位分配 GBS 角色,并同步岗位下人员 |
|
||||
| GET | `/safetyEval/org-position/gbs-roles` | 拉取 GBS 角色列表(下拉) |
|
||||
| POST | `/safetyEval/org-position/modify` | 原编辑接口;若岗位已有 GBS 角色且有人员,则同步人员角色 |
|
||||
|
||||
|
||||
分配入参 `OrgPositionAssignGbsRoleCmd`:`id`、`gbsRoleId`、`gbsRoleCode`、`gbsRoleName`(可选,空则尝试按 code 反查名称)。
|
||||
|
||||
## 5. 业务流程
|
||||
|
||||
|
||||
|
||||
### 5.1 分配角色
|
||||
|
||||
```mermaid
|
||||
|
|
@ -93,6 +105,10 @@ sequenceDiagram
|
|||
EXE-->>UI: 岗位 CO(含角色)
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### 5.2 编辑岗位时同步
|
||||
|
||||
```mermaid
|
||||
|
|
@ -106,6 +122,10 @@ flowchart TD
|
|||
E --> Z
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### 5.4 人员新增时角色
|
||||
|
||||
```mermaid
|
||||
|
|
@ -117,6 +137,10 @@ flowchart TD
|
|||
C -->|否| D
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
### 5.3 硬编码角色使用约定
|
||||
|
||||
```mermaid
|
||||
|
|
@ -127,6 +151,10 @@ flowchart LR
|
|||
CODE --> LOGIC[开展业务逻辑]
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## 6. 前端使用流程
|
||||
|
||||
路径:`/safetyEval/container/EnterpriseInfo/DepartmentPosition`
|
||||
|
|
@ -136,13 +164,18 @@ flowchart LR
|
|||
3. 弹窗从 `/gbs-roles` 加载下拉,选择后提交 `/assign-gbs-role`。
|
||||
4. 若该岗位已有人员,后端依次更新其 GBS 角色后返回成功。
|
||||
|
||||
|
||||
|
||||
## 7. 关键代码索引
|
||||
|
||||
| 层级 | 位置 |
|
||||
|------|------|
|
||||
| 枚举 | `client/enums/GbsRoleEnum` |
|
||||
| API | `OrgPositionApi#assignGbsRole` / `#listGbsRoles` |
|
||||
| 执行 | `OrgPositionExecutor` |
|
||||
|
||||
| 层级 | 位置 |
|
||||
| ------ | --------------------------------------------------------------------- |
|
||||
| 枚举 | `client/enums/GbsRoleEnum` |
|
||||
| API | `OrgPositionApi#assignGbsRole` / `#listGbsRoles` |
|
||||
| 执行 | `OrgPositionExecutor` |
|
||||
| GBS 用户 | `GbsUserFacadeClient#updateUserRole` / `#updateUserRolesSequentially` |
|
||||
| GBS 角色 | `GbsRoleFacadeClient#listRoles` |
|
||||
| 前端 | `DepartmentPosition` + `api/orgPosition` |
|
||||
| GBS 角色 | `GbsRoleFacadeClient#listRoles` |
|
||||
| 前端 | `DepartmentPosition` + `api/orgPosition` |
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,50 @@
|
|||
# 机构端报告库 · 原型对照与缺口说明
|
||||
|
||||
> 原型模块:`mod-institution-report-library`(`institution.html`)
|
||||
> OpenAPI(Apifox):[`docs/openapi/机构端-安评报告库.openapi.yaml`](../openapi/机构端-安评报告库.openapi.yaml)
|
||||
> 库表增量:[`docs/db/alter-eval-report-library-fields.sql`](../db/alter-eval-report-library-fields.sql)
|
||||
|
||||
## 1. 原型展示与功能清单
|
||||
|
||||
| 区域 | 原型内容 | 后端 |
|
||||
|------|----------|------|
|
||||
| 页头 | 标题 +「上传历史报告」 | `POST /add` |
|
||||
| 汇总卡 | 总数 / 近三年 / 已报送 / 待完善 / 抽查中 | `GET /summary` |
|
||||
| 筛选 | 名称编号、年度、评价类型、行业、报送状态 | `GET /page` 参数 |
|
||||
| 列表列 | 编号、名称、年度、类型、行业、被评价单位、签发日期、报送状态 | `EvalReportLibraryCO` |
|
||||
| 操作 | 查看、下载 | `GET /get`(`fileUrl` 下载) |
|
||||
| 上传弹窗 | 文件+编号/名称/年度/类型/行业/单位/签发日/页数/是否报送/保密/备注 | `POST /add` |
|
||||
| 报送 | 未报送→已报送 | `POST /submit` |
|
||||
| 抽查整改 | (列表详情联动) | `/eval-report-spotcheck/**` |
|
||||
|
||||
## 2. 字段映射
|
||||
|
||||
| 原型 | 字段 |
|
||||
|------|------|
|
||||
| 所属行业 | `industry_code` / `industry_name` |
|
||||
| 被评价单位 | `evaluated_unit_name` |
|
||||
| 签发日期 | `issue_date` |
|
||||
| 页数 | `page_count` |
|
||||
| 保密属性 | `secret_level_code` / `secret_level_name` |
|
||||
| 是否报送监管 | `submit_flag`(1是 2否) |
|
||||
| 列表报送状态文案 | `displayStatusName`(计算:未报送/已报送/抽查中/整改中/已复核) |
|
||||
| 抽查流转状态 | `report_status_code`(1~4,既有) |
|
||||
|
||||
## 3. 接口一览
|
||||
|
||||
| 方法 | 路径 | 说明 |
|
||||
|------|------|------|
|
||||
| GET | `/safetyEval/institution/eval-report/summary` | 汇总 |
|
||||
| GET | `/safetyEval/institution/eval-report/page` | 分页 |
|
||||
| GET | `/safetyEval/institution/eval-report/get` | 详情 |
|
||||
| POST | `/safetyEval/institution/eval-report/add` | 上传历史报告 |
|
||||
| POST | `/safetyEval/institution/eval-report/submit` | 报送监管 |
|
||||
| GET | `/safetyEval/institution/eval-report-spotcheck/list` | 抽查列表 |
|
||||
| GET | `/safetyEval/institution/eval-report-spotcheck/get` | 抽查详情 |
|
||||
| POST | `/safetyEval/institution/eval-report-spotcheck/rectify` | 整改反馈 |
|
||||
|
||||
## 4. 上线注意
|
||||
|
||||
1. 执行 `alter-eval-report-library-fields.sql`(存量库)。
|
||||
2. 历史数据 `submit_flag` 默认 2;过程控制归档/监管补录写入时置 1。
|
||||
3. 上传文件走统一 OSS/文件上传拿 URL,本接口只存元数据与 URL。
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
# 监督检查告知 / 通知 — 原型对照
|
||||
|
||||
## 模块映射
|
||||
|
||||
| 端 | 原型 | 后端 |
|
||||
|----|------|------|
|
||||
| 监管 | `mod-inspection-notice` 监督检查告知 | `/safetyEval/regulator/insp-notice/**` |
|
||||
| 机构 | 消息入口 `mod-reg-message`(`pageCode=reg-message`,`bizType=insp_notice`)+ 告知办理 | `/safetyEval/institution/insp-notice/**` |
|
||||
|
||||
说明:机构端原型页「监督检查通知」是**监管消息中心**,除监督检查告知外,还包含风险预警产生的整改通知、核查函、补正通知等。后者属风险预警域,**不在本 insp_notice 接口范围内**。本接口仅覆盖 `insp_notice` 业务闭环。
|
||||
|
||||
## 监管端字段与能力
|
||||
|
||||
| 原型 | 后端 |
|
||||
|------|------|
|
||||
| 筛选:告知编号、评价机构、检查类型、来源方式、来源预警编号、检查负责人、检查时间起止、机构确认、材料反馈、办理状态 | `GET /page` 对应 query |
|
||||
| 列表:编号/机构/类型/计划时间/来源/负责人/确认/反馈/状态 | `RegulatorInspNoticeCO`(含 `orgName`、`sourceRefNo`、`feedbackFlag`) |
|
||||
| 新建 / 编辑待下发 | `POST /save`(status=0) |
|
||||
| 下发 | `POST /issue`(新建直发,或传 `id` 下发草稿) |
|
||||
| 查看 / 保存备注 | `GET /get`、`POST /remark` |
|
||||
| 登记结果 | `POST /close` |
|
||||
| 提醒 | `POST /urge` |
|
||||
| 下载记录 | `GET /download-record`(CSV) |
|
||||
| 导出台账 | `POST /export-ledger`(CSV) |
|
||||
| 材料只读 | `GET /materials` |
|
||||
|
||||
### 状态
|
||||
|
||||
| 原型 | statusCode | statusName |
|
||||
|------|------------|------------|
|
||||
| 待下发 | 0 | 待下发 |
|
||||
| 已下发 | 1 | 已下发 |
|
||||
| (机构已确认,列表可仍归「已下发」类展示) | 2 | 已确认 |
|
||||
| 已反馈 | 3 | 已反馈 |
|
||||
| 已完成 | 4 | 已办结 |
|
||||
|
||||
### 来源方式
|
||||
|
||||
| 原型 | sourceTypeCode |
|
||||
|------|----------------|
|
||||
| 年度计划 | 1 |
|
||||
| 专项安排 | 2 |
|
||||
| 其他 | 3 |
|
||||
| 风险预警 | 4 |
|
||||
|
||||
## 机构端(insp_notice)能力
|
||||
|
||||
| 能力 | 接口 |
|
||||
|------|------|
|
||||
| 本机构告知分页(不含草稿) | `GET /page` |
|
||||
| 详情(含结果、监管备注) | `GET /get` |
|
||||
| 确认 | `POST /confirm` |
|
||||
| 上传材料 URL | `POST /material/upload` |
|
||||
| 提交材料反馈 | `POST /feedback` |
|
||||
| 材料列表 | `GET /materials` |
|
||||
|
||||
消息推送:下发/催办 → 机构消息(`pageCode=reg-message`);反馈 → 监管消息(`pageCode=inspection-notice`)。详见 `plans/phase2-prototype-api/baseline/p3-insp-rules.md`。
|
||||
|
||||
## 库表增量
|
||||
|
||||
执行 `docs/db/alter-insp-notice-prototype-fields.sql`(`source_ref_no`、`notice_urls`)。
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
# 监管端安评报告数据库 · 原型对照
|
||||
|
||||
> 原型:`regulator.html` → `mod-report-library`
|
||||
> OpenAPI:[`docs/openapi/监管端-安评报告数据库.openapi.yaml`](../openapi/监管端-安评报告数据库.openapi.yaml)
|
||||
> 机构端对照:[`docs/openapi/机构端-安评报告库.openapi.yaml`](../openapi/机构端-安评报告库.openapi.yaml)
|
||||
|
||||
## 1. 原型能力
|
||||
|
||||
| 区域 | 内容 | 后端策略 |
|
||||
|------|------|----------|
|
||||
| 说明 | 接收机构正式报告;AI 辅助研判 | AI **不做后端** |
|
||||
| 汇总 | 近三年 / 本年度 | `GET /summary` |
|
||||
| 筛选 | 名称编号、报送机构、年度、类型、行业、报送时间起止 | `GET /page` |
|
||||
| 列表 | 编号、名称、机构、类型、行业、签发日、报送时间 | CO 含 `orgName` 等 |
|
||||
| 操作 | 查看报告、AI分析 | 查看=`/get`;AI=前端静态 |
|
||||
| 工具栏 | 批量下载、导出目录 | `POST /batch-download`(ZIP)、`POST /export-catalog`(CSV) |
|
||||
| 补录 | (业务闭环需要) | `POST /add`,字段对齐机构端 |
|
||||
| 抽查闭环 | 本页列表无直出按钮,但与机构整改对应 | `/eval-report-spotcheck/**` |
|
||||
|
||||
## 2. 与机构端对应关系
|
||||
|
||||
```text
|
||||
机构上传/归档/报送(submit_flag=1)
|
||||
↓
|
||||
监管报告数据库可见(默认仅已报送)
|
||||
↓
|
||||
监管发起抽查 → 机构整改 → 监管复核
|
||||
```
|
||||
|
||||
| 机构端 | 监管端 |
|
||||
|--------|--------|
|
||||
| `POST .../eval-report/add`(可仅存库) | 库中默认不可见直至报送 |
|
||||
| `POST .../eval-report/submit` | 进入监管库 |
|
||||
| 过程控制 archive | `submit_flag=1` 进入监管库 |
|
||||
| `POST .../spotcheck/rectify` | `POST .../spotcheck/start` + `review` |
|
||||
|
||||
## 3. 本次相对原 P4 的补齐
|
||||
|
||||
- 汇总接口、关键词/机构名/行业/报送时间筛选
|
||||
- 列表回填 `orgName`
|
||||
- 补录字段与机构端上传对齐(行业、被评价单位、签发日、页数、保密等)
|
||||
- **批量下载**:按勾选 ID 打包 ZIP(最多 50 份,拉取各报告 `fileUrl`)
|
||||
- **导出目录**:CSV(Excel 可开);勾选优先,否则按当前筛选/全部已报送(最多 5000 行)
|
||||
- 独立 Apifox OpenAPI(含抽查闭环与上述导出下载)
|
||||
|
|
@ -0,0 +1,412 @@
|
|||
openapi: 3.0.3
|
||||
info:
|
||||
title: 机构端-安评报告库 API
|
||||
description: |
|
||||
对齐原型页 `institution-report-library`(机构端「报告库」)的展示与功能。
|
||||
|
||||
## 原型能力对照
|
||||
| 原型 | 接口 |
|
||||
|------|------|
|
||||
| 顶栏汇总(总数/近三年/已报送/待完善/抽查中) | `GET /summary` |
|
||||
| 列表筛选(名称编号/年度/评价类型/行业/报送状态) | `GET /page` |
|
||||
| 查看详情 | `GET /get` |
|
||||
| 下载 | 详情 `fileUrl` 由前端下载(无单独下载流接口) |
|
||||
| 上传历史报告 | `POST /add`(文件先走统一上传拿 URL) |
|
||||
| 报送监管 | `POST /submit` |
|
||||
| 抽查记录/整改 | `/eval-report-spotcheck/**` |
|
||||
|
||||
**Apifox 导入**:项目设置 → 导入数据 → OpenAPI → 选择本文件。
|
||||
|
||||
统一前缀:`/safetyEval/institution`
|
||||
成功:`success=true` 且 `code="0"`
|
||||
version: 1.1.0
|
||||
contact:
|
||||
name: safety-eval-service
|
||||
|
||||
servers:
|
||||
- url: http://localhost:8095
|
||||
description: 本地开发
|
||||
- url: http://192.168.20.100:30140
|
||||
description: 测试网关(100)
|
||||
|
||||
tags:
|
||||
- name: 机构端-安评报告库
|
||||
description: 报告库列表/详情/上传/报送/汇总
|
||||
- name: 机构端-报告抽查整改
|
||||
description: 抽查记录查询与整改反馈
|
||||
|
||||
paths:
|
||||
/safetyEval/institution/eval-report/summary:
|
||||
get:
|
||||
tags: [机构端-安评报告库]
|
||||
summary: 报告库页顶栏汇总
|
||||
operationId: institutionEvalReportSummary
|
||||
responses:
|
||||
'200':
|
||||
description: 成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SingleResponseInstitutionEvalReportSummaryCO'
|
||||
example:
|
||||
success: true
|
||||
code: "0"
|
||||
data:
|
||||
totalCount: 126
|
||||
recentThreeYearCount: 98
|
||||
submittedCount: 86
|
||||
incompleteCount: 5
|
||||
spotcheckingCount: 3
|
||||
|
||||
/safetyEval/institution/eval-report/page:
|
||||
get:
|
||||
tags: [机构端-安评报告库]
|
||||
summary: 分页查询本机构报告
|
||||
operationId: institutionEvalReportPage
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/current'
|
||||
- $ref: '#/components/parameters/size'
|
||||
- name: keyword
|
||||
in: query
|
||||
description: 报告名称 / 编号
|
||||
schema: { type: string }
|
||||
- name: reportYear
|
||||
in: query
|
||||
schema: { type: integer, example: 2026 }
|
||||
- name: evalTypeCode
|
||||
in: query
|
||||
description: PRE / ACCEPT / STATUS
|
||||
schema: { type: string, example: PRE }
|
||||
- name: industryCode
|
||||
in: query
|
||||
description: 所属行业编码,如 HAZCHEM
|
||||
schema: { type: string }
|
||||
- name: reportStatusCode
|
||||
in: query
|
||||
description: 1已入库 2抽查中 3待整改 4已复核
|
||||
schema: { type: integer }
|
||||
- name: displayStatus
|
||||
in: query
|
||||
description: |
|
||||
原型「报送状态」筛选:
|
||||
`UN_SUBMITTED` 未报送 /
|
||||
`SUBMITTED` 已报送 /
|
||||
`SPOTCHECKING` 抽查中 /
|
||||
`RECTIFYING` 整改中 /
|
||||
`REVIEWED` 已复核
|
||||
schema:
|
||||
type: string
|
||||
enum: [UN_SUBMITTED, SUBMITTED, SPOTCHECKING, RECTIFYING, REVIEWED]
|
||||
responses:
|
||||
'200':
|
||||
description: 成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/PageResponseEvalReportLibraryCO'
|
||||
|
||||
/safetyEval/institution/eval-report/get:
|
||||
get:
|
||||
tags: [机构端-安评报告库]
|
||||
summary: 报告详情
|
||||
description: 含 `fileUrl`/`fileName`,前端下载直接使用文件地址。
|
||||
operationId: institutionEvalReportGet
|
||||
parameters:
|
||||
- name: id
|
||||
in: query
|
||||
required: true
|
||||
schema: { type: string }
|
||||
responses:
|
||||
'200':
|
||||
description: 成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SingleResponseEvalReportLibraryCO'
|
||||
|
||||
/safetyEval/institution/eval-report/add:
|
||||
post:
|
||||
tags: [机构端-安评报告库]
|
||||
summary: 上传历史报告
|
||||
description: |
|
||||
对齐原型弹窗「上传历史报告」。
|
||||
文件请先调用统一文件上传接口拿到 `fileUrl` 再提交本接口。
|
||||
`submitToRegulator=true` 时 `submitFlag=1`(已报送);否则 `submitFlag=2`(未报送)。
|
||||
同机构下 `reportNo` 不可重复。
|
||||
operationId: institutionEvalReportAdd
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/InstitutionEvalReportAddCmd'
|
||||
example:
|
||||
reportNo: CQAP-XZ-2026-001
|
||||
reportName: 华安化工园区建设项目安全预评价报告
|
||||
reportYear: 2026
|
||||
evalTypeCode: PRE
|
||||
evalTypeName: 安全预评价
|
||||
industryCode: HAZCHEM
|
||||
industryName: 危险化学品
|
||||
evaluatedUnitName: 重庆华安化工有限公司
|
||||
issueDate: '2026-07-16'
|
||||
pageCount: 186
|
||||
fileUrl: https://oss.example.com/reports/xxx.pdf
|
||||
fileName: 华安化工预评价.pdf
|
||||
secretLevelCode: NORMAL
|
||||
secretLevelName: 普通
|
||||
remarks: 正式签章版
|
||||
submitToRegulator: false
|
||||
responses:
|
||||
'200':
|
||||
description: 成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SingleResponseEvalReportLibraryCO'
|
||||
|
||||
/safetyEval/institution/eval-report/submit:
|
||||
post:
|
||||
tags: [机构端-安评报告库]
|
||||
summary: 报送监管
|
||||
description: 将 `submitFlag=2`(未报送)的报告改为已报送;已报送则报错 06-07-009。
|
||||
operationId: institutionEvalReportSubmit
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/InstitutionEvalReportSubmitCmd'
|
||||
example:
|
||||
id: 10001
|
||||
responses:
|
||||
'200':
|
||||
description: 成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SingleResponseEvalReportLibraryCO'
|
||||
|
||||
/safetyEval/institution/eval-report-spotcheck/list:
|
||||
get:
|
||||
tags: [机构端-报告抽查整改]
|
||||
summary: 按报告查询抽查记录
|
||||
operationId: institutionSpotcheckList
|
||||
parameters:
|
||||
- name: reportId
|
||||
in: query
|
||||
required: true
|
||||
schema: { type: integer, format: int64 }
|
||||
responses:
|
||||
'200':
|
||||
description: 成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SingleResponseEvalReportSpotcheckCOList'
|
||||
|
||||
/safetyEval/institution/eval-report-spotcheck/get:
|
||||
get:
|
||||
tags: [机构端-报告抽查整改]
|
||||
summary: 抽查详情
|
||||
operationId: institutionSpotcheckGet
|
||||
parameters:
|
||||
- name: id
|
||||
in: query
|
||||
required: true
|
||||
schema: { type: string }
|
||||
responses:
|
||||
'200':
|
||||
description: 成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SingleResponseEvalReportSpotcheckCO'
|
||||
|
||||
/safetyEval/institution/eval-report-spotcheck/rectify:
|
||||
post:
|
||||
tags: [机构端-报告抽查整改]
|
||||
summary: 提交整改反馈
|
||||
description: 报告须处于抽查中且抽查结果为不合格。
|
||||
operationId: institutionSpotcheckRectify
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/InstitutionSpotcheckRectifyCmd'
|
||||
example:
|
||||
spotcheckId: 20001
|
||||
rectifyFeedback: 已按抽查意见完成修订并重新盖章
|
||||
responses:
|
||||
'200':
|
||||
description: 成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SingleResponseEvalReportSpotcheckCO'
|
||||
|
||||
components:
|
||||
parameters:
|
||||
current:
|
||||
name: current
|
||||
in: query
|
||||
description: 页码(从 1 开始)
|
||||
schema: { type: integer, default: 1 }
|
||||
size:
|
||||
name: size
|
||||
in: query
|
||||
description: 每页条数
|
||||
schema: { type: integer, default: 10 }
|
||||
|
||||
schemas:
|
||||
SingleResponseBase:
|
||||
type: object
|
||||
properties:
|
||||
success: { type: boolean, example: true }
|
||||
code: { type: string, example: "0" }
|
||||
message: { type: string }
|
||||
errCode: { type: string }
|
||||
errMessage: { type: string }
|
||||
|
||||
EvalReportLibraryCO:
|
||||
type: object
|
||||
properties:
|
||||
id: { type: string }
|
||||
orgId: { type: string }
|
||||
projectId: { type: string }
|
||||
customerId: { type: string }
|
||||
evaluatedUnitName: { type: string, description: 被评价单位 }
|
||||
reportNo: { type: string }
|
||||
reportName: { type: string }
|
||||
reportYear: { type: integer }
|
||||
evalTypeCode: { type: string, example: PRE }
|
||||
evalTypeName: { type: string, example: 安全预评价 }
|
||||
industryCode: { type: string, example: HAZCHEM }
|
||||
industryName: { type: string, example: 危险化学品 }
|
||||
businessScope: { type: string }
|
||||
fileUrl: { type: string }
|
||||
fileName: { type: string }
|
||||
publicFlag: { type: integer, description: "1是2否" }
|
||||
completeFlag: { type: integer, description: "1完整2待完善" }
|
||||
submitFlag: { type: integer, description: "1已报送2未报送" }
|
||||
reportStatusCode: { type: integer, description: "1已入库2抽查中3待整改4已复核" }
|
||||
reportStatusName: { type: string }
|
||||
displayStatusName:
|
||||
type: string
|
||||
description: 列表展示报送状态(未报送/已报送/抽查中/整改中/已复核)
|
||||
example: 已报送
|
||||
archiveTime: { type: string, format: date-time }
|
||||
issueDate: { type: string, format: date, description: 签发日期 }
|
||||
pageCount: { type: integer }
|
||||
secretLevelCode: { type: string, example: NORMAL }
|
||||
secretLevelName: { type: string, example: 普通 }
|
||||
remarks: { type: string }
|
||||
|
||||
InstitutionEvalReportSummaryCO:
|
||||
type: object
|
||||
properties:
|
||||
totalCount: { type: integer, format: int64 }
|
||||
recentThreeYearCount: { type: integer, format: int64 }
|
||||
submittedCount: { type: integer, format: int64 }
|
||||
incompleteCount: { type: integer, format: int64 }
|
||||
spotcheckingCount: { type: integer, format: int64 }
|
||||
|
||||
InstitutionEvalReportAddCmd:
|
||||
type: object
|
||||
required: [reportNo, reportName, evaluatedUnitName, issueDate, fileUrl]
|
||||
properties:
|
||||
reportNo: { type: string }
|
||||
reportName: { type: string }
|
||||
reportYear: { type: integer }
|
||||
evalTypeCode: { type: string }
|
||||
evalTypeName: { type: string }
|
||||
industryCode: { type: string }
|
||||
industryName: { type: string }
|
||||
evaluatedUnitName: { type: string }
|
||||
customerId: { type: integer, format: int64 }
|
||||
issueDate: { type: string, format: date }
|
||||
pageCount: { type: integer }
|
||||
fileUrl: { type: string }
|
||||
fileName: { type: string }
|
||||
secretLevelCode: { type: string }
|
||||
secretLevelName: { type: string }
|
||||
remarks: { type: string }
|
||||
submitToRegulator: { type: boolean, description: true=同步报送监管 }
|
||||
|
||||
InstitutionEvalReportSubmitCmd:
|
||||
type: object
|
||||
required: [id]
|
||||
properties:
|
||||
id: { type: integer, format: int64 }
|
||||
|
||||
EvalReportSpotcheckCO:
|
||||
type: object
|
||||
properties:
|
||||
id: { type: string }
|
||||
orgId: { type: string }
|
||||
reportId: { type: string }
|
||||
checkResultCode: { type: integer, description: "1合格2不合格" }
|
||||
checkResultName: { type: string }
|
||||
checkOpinion: { type: string }
|
||||
rectifyRequire: { type: string }
|
||||
rectifyFeedback: { type: string }
|
||||
reviewResultCode: { type: integer, description: "1通过2不通过" }
|
||||
reviewResultName: { type: string }
|
||||
checkerId: { type: string }
|
||||
checkerName: { type: string }
|
||||
checkTime: { type: string, format: date-time }
|
||||
|
||||
InstitutionSpotcheckRectifyCmd:
|
||||
type: object
|
||||
required: [spotcheckId, rectifyFeedback]
|
||||
properties:
|
||||
spotcheckId: { type: integer, format: int64 }
|
||||
rectifyFeedback: { type: string }
|
||||
|
||||
SingleResponseEvalReportLibraryCO:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/SingleResponseBase'
|
||||
- type: object
|
||||
properties:
|
||||
data:
|
||||
$ref: '#/components/schemas/EvalReportLibraryCO'
|
||||
|
||||
SingleResponseInstitutionEvalReportSummaryCO:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/SingleResponseBase'
|
||||
- type: object
|
||||
properties:
|
||||
data:
|
||||
$ref: '#/components/schemas/InstitutionEvalReportSummaryCO'
|
||||
|
||||
PageResponseEvalReportLibraryCO:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/SingleResponseBase'
|
||||
- type: object
|
||||
properties:
|
||||
data:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/EvalReportLibraryCO'
|
||||
total:
|
||||
type: integer
|
||||
format: int64
|
||||
|
||||
SingleResponseEvalReportSpotcheckCO:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/SingleResponseBase'
|
||||
- type: object
|
||||
properties:
|
||||
data:
|
||||
$ref: '#/components/schemas/EvalReportSpotcheckCO'
|
||||
|
||||
SingleResponseEvalReportSpotcheckCOList:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/SingleResponseBase'
|
||||
- type: object
|
||||
properties:
|
||||
data:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/EvalReportSpotcheckCO'
|
||||
|
|
@ -0,0 +1,726 @@
|
|||
openapi: 3.0.3
|
||||
info:
|
||||
title: 监督检查告知 / 通知 API
|
||||
description: |
|
||||
对齐原型:
|
||||
- 监管端 `mod-inspection-notice`(监督检查告知)
|
||||
- 机构端消息入口 `reg-message` 中 `bizType=insp_notice` 的办理能力
|
||||
|
||||
## 原型能力对照(监管)
|
||||
| 原型 | 后端 |
|
||||
|------|------|
|
||||
| 筛选编号/机构/类型/来源/预警号/负责人/时间/确认/反馈/状态 | `GET .../regulator/insp-notice/page` |
|
||||
| 列表含机构名、来源预警号、确认与反馈 | `RegulatorInspNoticeCO` |
|
||||
| 新建/编辑待下发 | `POST .../save` |
|
||||
| 下发 | `POST .../issue`(新建或 `id` 下发草稿) |
|
||||
| 查看 / 保存备注 | `GET .../get`、`POST .../remark` |
|
||||
| 登记结果 | `POST .../close` |
|
||||
| 提醒 | `POST .../urge` |
|
||||
| 下载记录 | `GET .../download-record` |
|
||||
| 导出台账 | `POST .../export-ledger` |
|
||||
| 材料只读 | `GET .../materials` |
|
||||
|
||||
## 原型能力对照(机构 · insp_notice)
|
||||
| 能力 | 后端 |
|
||||
|------|------|
|
||||
| 本机构告知列表/详情 | `GET .../institution/insp-notice/page|get` |
|
||||
| 确认 / 上传材料 / 反馈 | `POST .../confirm|material/upload|feedback` |
|
||||
| 材料列表 | `GET .../materials` |
|
||||
|
||||
**说明**:机构端原型「监督检查通知」整页还聚合风险预警类整改/核查/补正消息,不在本文件范围内。
|
||||
|
||||
**字典**
|
||||
- 状态:`0待下发 1已下发 2已确认 3已反馈 4已办结`(原型「已完成」=`4`)
|
||||
- 来源:`1年度计划 2专项安排 3其他 4风险预警`
|
||||
- 结果:`1未发现问题/合格 2责令整改/不合格 3转入风险预警/限期整改`
|
||||
- 确认/反馈:`1是/已提交 2否/未提交`
|
||||
|
||||
**Apifox 导入**:项目设置 → 导入数据 → OpenAPI → 选择本文件。
|
||||
|
||||
成功:`success=true` 且 `code="0"`(文件流接口直接返回附件,失败时返回 JSON)
|
||||
version: 1.0.0
|
||||
contact:
|
||||
name: safety-eval-service
|
||||
|
||||
servers:
|
||||
- url: http://localhost:8095
|
||||
description: 本地开发
|
||||
- url: http://192.168.20.100:30140
|
||||
description: 测试网关(100)
|
||||
|
||||
tags:
|
||||
- name: 监管端-监督检查告知
|
||||
description: 告知新建/下发/跟踪/办结/导出
|
||||
- name: 机构端-监督检查告知
|
||||
description: 确认、材料反馈、查看结果
|
||||
|
||||
paths:
|
||||
/safetyEval/regulator/insp-notice/save:
|
||||
post:
|
||||
tags: [监管端-监督检查告知]
|
||||
summary: 暂存/编辑待下发告知
|
||||
operationId: regulatorInspNoticeSave
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RegulatorInspNoticeSaveCmd'
|
||||
example:
|
||||
orgId: 10001
|
||||
inspTypeCode: SPECIAL
|
||||
inspTypeName: 专项检查
|
||||
sourceTypeCode: 1
|
||||
sourceTypeName: 年度计划
|
||||
planInspTime: "2026-08-05T09:00:00"
|
||||
leaderName: 周强
|
||||
noticeContent: 请准备专项检查材料
|
||||
materialNames: [项目过程记录, 人员到场记录]
|
||||
responses:
|
||||
'200':
|
||||
description: 成功(status=0 待下发)
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SingleResponseRegulatorInspNoticeCO'
|
||||
|
||||
/safetyEval/regulator/insp-notice/issue:
|
||||
post:
|
||||
tags: [监管端-监督检查告知]
|
||||
summary: 新建并下发,或下发草稿
|
||||
description: |
|
||||
- 传 `id`:将 status=0 草稿下发为已下发,并推送机构消息
|
||||
- 不传 `id`:直接新建并下发(需 `orgId`)
|
||||
operationId: regulatorInspNoticeIssue
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RegulatorInspNoticeIssueCmd'
|
||||
examples:
|
||||
issueDraft:
|
||||
summary: 下发草稿
|
||||
value: { id: 20001 }
|
||||
createAndIssue:
|
||||
summary: 新建并下发
|
||||
value:
|
||||
orgId: 10001
|
||||
inspTypeCode: PROJECT_PROCESS
|
||||
inspTypeName: 项目过程检查
|
||||
sourceTypeCode: 4
|
||||
sourceTypeName: 风险预警
|
||||
sourceRefNo: W-PROJ-2026-009
|
||||
planInspTime: "2026-07-22T09:30:00"
|
||||
leaderName: 刘敏
|
||||
noticeContent: 请准备项目过程记录、人员到场记录及相关证明材料
|
||||
materialNames: [联系人及准备材料清单]
|
||||
responses:
|
||||
'200':
|
||||
description: 成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SingleResponseRegulatorInspNoticeCO'
|
||||
|
||||
/safetyEval/regulator/insp-notice/page:
|
||||
get:
|
||||
tags: [监管端-监督检查告知]
|
||||
summary: 分页查询告知
|
||||
operationId: regulatorInspNoticePage
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/current'
|
||||
- $ref: '#/components/parameters/size'
|
||||
- name: noticeNo
|
||||
in: query
|
||||
schema: { type: string }
|
||||
- name: orgId
|
||||
in: query
|
||||
schema: { type: integer, format: int64 }
|
||||
- name: orgName
|
||||
in: query
|
||||
description: 评价机构名称(模糊)
|
||||
schema: { type: string }
|
||||
- name: keyword
|
||||
in: query
|
||||
schema: { type: string }
|
||||
- name: inspTypeCode
|
||||
in: query
|
||||
schema: { type: string, enum: [PROJECT_PROCESS, QUAL_KEEP, SPECIAL] }
|
||||
- name: sourceTypeCode
|
||||
in: query
|
||||
schema: { type: integer, enum: [1, 2, 3, 4] }
|
||||
- name: sourceRefNo
|
||||
in: query
|
||||
description: 来源预警编号
|
||||
schema: { type: string }
|
||||
- name: leaderName
|
||||
in: query
|
||||
schema: { type: string }
|
||||
- name: planInspTimeStart
|
||||
in: query
|
||||
description: yyyy-MM-dd
|
||||
schema: { type: string }
|
||||
- name: planInspTimeEnd
|
||||
in: query
|
||||
description: yyyy-MM-dd
|
||||
schema: { type: string }
|
||||
- name: confirmFlag
|
||||
in: query
|
||||
description: 1已确认 2未确认
|
||||
schema: { type: integer, enum: [1, 2] }
|
||||
- name: feedbackFlag
|
||||
in: query
|
||||
description: 1已提交 2未提交
|
||||
schema: { type: integer, enum: [1, 2] }
|
||||
- name: statusCode
|
||||
in: query
|
||||
description: 0待下发 1已下发 2已确认 3已反馈 4已办结
|
||||
schema: { type: integer, enum: [0, 1, 2, 3, 4] }
|
||||
responses:
|
||||
'200':
|
||||
description: 成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/PageResponseRegulatorInspNoticeCO'
|
||||
|
||||
/safetyEval/regulator/insp-notice/get:
|
||||
get:
|
||||
tags: [监管端-监督检查告知]
|
||||
summary: 查询告知详情
|
||||
operationId: regulatorInspNoticeGet
|
||||
parameters:
|
||||
- name: id
|
||||
in: query
|
||||
required: true
|
||||
schema: { type: string }
|
||||
responses:
|
||||
'200':
|
||||
description: 成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SingleResponseRegulatorInspNoticeCO'
|
||||
|
||||
/safetyEval/regulator/insp-notice/close:
|
||||
post:
|
||||
tags: [监管端-监督检查告知]
|
||||
summary: 登记结果并办结
|
||||
description: 前置状态须为已确认(2)或已反馈(3)
|
||||
operationId: regulatorInspNoticeClose
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RegulatorInspNoticeCloseCmd'
|
||||
example:
|
||||
id: 20001
|
||||
resultCode: 2
|
||||
resultName: 责令整改
|
||||
resultContent: 现场检查发现问题,限期整改
|
||||
resultUrls: ["https://example.com/record.pdf"]
|
||||
responses:
|
||||
'200':
|
||||
description: 成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SingleResponseRegulatorInspNoticeCO'
|
||||
|
||||
/safetyEval/regulator/insp-notice/remark:
|
||||
post:
|
||||
tags: [监管端-监督检查告知]
|
||||
summary: 保存监管备注
|
||||
operationId: regulatorInspNoticeRemark
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RegulatorInspNoticeRemarkCmd'
|
||||
responses:
|
||||
'200':
|
||||
description: 成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SingleResponseRegulatorInspNoticeCO'
|
||||
|
||||
/safetyEval/regulator/insp-notice/materials:
|
||||
get:
|
||||
tags: [监管端-监督检查告知]
|
||||
summary: 材料只读列表
|
||||
operationId: regulatorInspNoticeMaterials
|
||||
parameters:
|
||||
- name: noticeId
|
||||
in: query
|
||||
required: true
|
||||
schema: { type: integer, format: int64 }
|
||||
responses:
|
||||
'200':
|
||||
description: 成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SingleResponseInspNoticeMaterialCOList'
|
||||
|
||||
/safetyEval/regulator/insp-notice/urge:
|
||||
post:
|
||||
tags: [监管端-监督检查告知]
|
||||
summary: 催办(重发机构消息)
|
||||
operationId: regulatorInspNoticeUrge
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RegulatorInspNoticeUrgeCmd'
|
||||
responses:
|
||||
'200':
|
||||
description: 成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SingleResponseVoid'
|
||||
|
||||
/safetyEval/regulator/insp-notice/export-ledger:
|
||||
post:
|
||||
tags: [监管端-监督检查告知]
|
||||
summary: 导出台账(CSV)
|
||||
description: 勾选优先;否则按筛选;最多 5000 行。直接下载文件。
|
||||
operationId: regulatorInspNoticeExportLedger
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RegulatorInspNoticeExportCmd'
|
||||
responses:
|
||||
'200':
|
||||
description: CSV 文件流;失败时 JSON
|
||||
content:
|
||||
text/csv:
|
||||
schema: { type: string, format: binary }
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SingleResponseBase'
|
||||
|
||||
/safetyEval/regulator/insp-notice/download-record:
|
||||
get:
|
||||
tags: [监管端-监督检查告知]
|
||||
summary: 下载检查记录(CSV)
|
||||
operationId: regulatorInspNoticeDownloadRecord
|
||||
parameters:
|
||||
- name: id
|
||||
in: query
|
||||
required: true
|
||||
schema: { type: integer, format: int64 }
|
||||
responses:
|
||||
'200':
|
||||
description: CSV 文件流;失败时 JSON
|
||||
content:
|
||||
text/csv:
|
||||
schema: { type: string, format: binary }
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SingleResponseBase'
|
||||
|
||||
/safetyEval/institution/insp-notice/page:
|
||||
get:
|
||||
tags: [机构端-监督检查告知]
|
||||
summary: 分页查询本机构告知(不含待下发草稿)
|
||||
operationId: institutionInspNoticePage
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/current'
|
||||
- $ref: '#/components/parameters/size'
|
||||
- name: noticeNo
|
||||
in: query
|
||||
schema: { type: string }
|
||||
- name: keyword
|
||||
in: query
|
||||
schema: { type: string }
|
||||
- name: inspTypeCode
|
||||
in: query
|
||||
schema: { type: string }
|
||||
- name: sourceTypeCode
|
||||
in: query
|
||||
schema: { type: integer }
|
||||
- name: sourceRefNo
|
||||
in: query
|
||||
schema: { type: string }
|
||||
- name: confirmFlag
|
||||
in: query
|
||||
schema: { type: integer }
|
||||
- name: feedbackFlag
|
||||
in: query
|
||||
schema: { type: integer }
|
||||
- name: statusCode
|
||||
in: query
|
||||
description: 1已下发 2已确认 3已反馈 4已办结
|
||||
schema: { type: integer, enum: [1, 2, 3, 4] }
|
||||
responses:
|
||||
'200':
|
||||
description: 成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/PageResponseInstitutionInspNoticeCO'
|
||||
|
||||
/safetyEval/institution/insp-notice/get:
|
||||
get:
|
||||
tags: [机构端-监督检查告知]
|
||||
summary: 查询告知详情
|
||||
operationId: institutionInspNoticeGet
|
||||
parameters:
|
||||
- name: id
|
||||
in: query
|
||||
required: true
|
||||
schema: { type: string }
|
||||
responses:
|
||||
'200':
|
||||
description: 成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SingleResponseInstitutionInspNoticeCO'
|
||||
|
||||
/safetyEval/institution/insp-notice/confirm:
|
||||
post:
|
||||
tags: [机构端-监督检查告知]
|
||||
summary: 确认告知
|
||||
description: 前置 status=1 已下发 → 2 已确认
|
||||
operationId: institutionInspNoticeConfirm
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required: [id]
|
||||
properties:
|
||||
id: { type: integer, format: int64 }
|
||||
responses:
|
||||
'200':
|
||||
description: 成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SingleResponseInstitutionInspNoticeCO'
|
||||
|
||||
/safetyEval/institution/insp-notice/material/upload:
|
||||
post:
|
||||
tags: [机构端-监督检查告知]
|
||||
summary: 上传材料(仅 URL)
|
||||
description: 前置告知状态为已确认或已反馈
|
||||
operationId: institutionInspNoticeMaterialUpload
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/InstitutionInspNoticeMaterialUploadCmd'
|
||||
responses:
|
||||
'200':
|
||||
description: 成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SingleResponseInspNoticeMaterialCO'
|
||||
|
||||
/safetyEval/institution/insp-notice/feedback:
|
||||
post:
|
||||
tags: [机构端-监督检查告知]
|
||||
summary: 提交材料反馈
|
||||
description: 前置 status=2;必填材料须已上传
|
||||
operationId: institutionInspNoticeFeedback
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/InstitutionInspNoticeFeedbackCmd'
|
||||
responses:
|
||||
'200':
|
||||
description: 成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SingleResponseInstitutionInspNoticeCO'
|
||||
|
||||
/safetyEval/institution/insp-notice/materials:
|
||||
get:
|
||||
tags: [机构端-监督检查告知]
|
||||
summary: 材料列表
|
||||
operationId: institutionInspNoticeMaterials
|
||||
parameters:
|
||||
- name: noticeId
|
||||
in: query
|
||||
required: true
|
||||
schema: { type: integer, format: int64 }
|
||||
responses:
|
||||
'200':
|
||||
description: 成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SingleResponseInspNoticeMaterialCOList'
|
||||
|
||||
components:
|
||||
parameters:
|
||||
current:
|
||||
name: current
|
||||
in: query
|
||||
schema: { type: integer, format: int64, default: 1 }
|
||||
size:
|
||||
name: size
|
||||
in: query
|
||||
schema: { type: integer, format: int64, default: 10 }
|
||||
|
||||
schemas:
|
||||
SingleResponseBase:
|
||||
type: object
|
||||
properties:
|
||||
success: { type: boolean, example: true }
|
||||
code: { type: string, example: "0" }
|
||||
errMessage: { type: string, nullable: true }
|
||||
traceId: { type: string, nullable: true }
|
||||
|
||||
RegulatorInspNoticeCO:
|
||||
type: object
|
||||
properties:
|
||||
id: { type: string }
|
||||
orgId: { type: string }
|
||||
orgName: { type: string, description: 评价机构名称 }
|
||||
noticeNo: { type: string, example: JC2026000018 }
|
||||
inspTypeCode: { type: string, example: PROJECT_PROCESS }
|
||||
inspTypeName: { type: string, example: 项目过程检查 }
|
||||
sourceTypeCode: { type: integer, example: 4 }
|
||||
sourceTypeName: { type: string, example: 风险预警 }
|
||||
sourceRefId: { type: string }
|
||||
sourceRefNo: { type: string, example: W-PROJ-2026-009 }
|
||||
projectId: { type: string }
|
||||
planInspTime: { type: string, format: date-time }
|
||||
leaderName: { type: string }
|
||||
noticeContent: { type: string }
|
||||
noticeUrls: { type: string }
|
||||
statusCode: { type: integer, example: 3 }
|
||||
statusName: { type: string, example: 已反馈 }
|
||||
confirmFlag: { type: integer, example: 1 }
|
||||
feedbackFlag: { type: integer, example: 1, description: 1已提交 2未提交 }
|
||||
confirmTime: { type: string, format: date-time }
|
||||
sendTime: { type: string, format: date-time }
|
||||
resultCode: { type: integer }
|
||||
resultName: { type: string }
|
||||
resultContent: { type: string }
|
||||
resultUrls: { type: string }
|
||||
resultRecorderName: { type: string }
|
||||
resultTime: { type: string, format: date-time }
|
||||
remarks: { type: string }
|
||||
|
||||
InstitutionInspNoticeCO:
|
||||
type: object
|
||||
properties:
|
||||
id: { type: string }
|
||||
noticeNo: { type: string }
|
||||
inspTypeCode: { type: string }
|
||||
inspTypeName: { type: string }
|
||||
sourceTypeCode: { type: integer }
|
||||
sourceTypeName: { type: string }
|
||||
sourceRefNo: { type: string }
|
||||
planInspTime: { type: string, format: date-time }
|
||||
leaderName: { type: string }
|
||||
noticeContent: { type: string }
|
||||
noticeUrls: { type: string }
|
||||
statusCode: { type: integer }
|
||||
statusName: { type: string }
|
||||
confirmFlag: { type: integer }
|
||||
feedbackFlag: { type: integer }
|
||||
confirmTime: { type: string, format: date-time }
|
||||
sendTime: { type: string, format: date-time }
|
||||
resultCode: { type: integer }
|
||||
resultName: { type: string }
|
||||
resultContent: { type: string }
|
||||
resultUrls: { type: string }
|
||||
resultTime: { type: string, format: date-time }
|
||||
remarks: { type: string }
|
||||
|
||||
InspNoticeMaterialCO:
|
||||
type: object
|
||||
properties:
|
||||
id: { type: string }
|
||||
noticeId: { type: string }
|
||||
materialName: { type: string }
|
||||
requiredFlag: { type: integer, description: 1必需 2非必需 }
|
||||
uploadStatusCode: { type: integer, description: 1待上传 2已上传 }
|
||||
uploadStatusName: { type: string }
|
||||
fileUrl: { type: string }
|
||||
|
||||
RegulatorInspNoticeSaveCmd:
|
||||
type: object
|
||||
required: [orgId]
|
||||
properties:
|
||||
id: { type: integer, format: int64, description: 空=新建草稿,非空=编辑待下发 }
|
||||
orgId: { type: integer, format: int64 }
|
||||
inspTypeCode: { type: string }
|
||||
inspTypeName: { type: string }
|
||||
sourceTypeCode: { type: integer }
|
||||
sourceTypeName: { type: string }
|
||||
sourceRefId: { type: integer, format: int64 }
|
||||
sourceRefNo: { type: string }
|
||||
projectId: { type: integer, format: int64 }
|
||||
planInspTime: { type: string, format: date-time }
|
||||
leaderName: { type: string }
|
||||
noticeContent: { type: string }
|
||||
noticeUrls:
|
||||
type: array
|
||||
items: { type: string }
|
||||
remarks: { type: string }
|
||||
materialNames:
|
||||
type: array
|
||||
items: { type: string }
|
||||
description: 仅新建草稿时预置材料行
|
||||
|
||||
RegulatorInspNoticeIssueCmd:
|
||||
type: object
|
||||
properties:
|
||||
id: { type: integer, format: int64, description: 传则下发草稿 }
|
||||
orgId: { type: integer, format: int64, description: 新建下发时必填 }
|
||||
inspTypeCode: { type: string }
|
||||
inspTypeName: { type: string }
|
||||
sourceTypeCode: { type: integer }
|
||||
sourceTypeName: { type: string }
|
||||
sourceRefId: { type: integer, format: int64 }
|
||||
sourceRefNo: { type: string }
|
||||
projectId: { type: integer, format: int64 }
|
||||
planInspTime: { type: string, format: date-time }
|
||||
leaderName: { type: string }
|
||||
noticeContent: { type: string }
|
||||
noticeUrls:
|
||||
type: array
|
||||
items: { type: string }
|
||||
remarks: { type: string }
|
||||
materialNames:
|
||||
type: array
|
||||
items: { type: string }
|
||||
|
||||
RegulatorInspNoticeCloseCmd:
|
||||
type: object
|
||||
required: [id]
|
||||
properties:
|
||||
id: { type: integer, format: int64 }
|
||||
resultCode: { type: integer, description: "1未发现问题 2责令整改 3转入风险预警" }
|
||||
resultName: { type: string }
|
||||
resultContent: { type: string }
|
||||
resultUrls:
|
||||
type: array
|
||||
items: { type: string }
|
||||
|
||||
RegulatorInspNoticeRemarkCmd:
|
||||
type: object
|
||||
required: [id]
|
||||
properties:
|
||||
id: { type: integer, format: int64 }
|
||||
remarks: { type: string }
|
||||
|
||||
RegulatorInspNoticeUrgeCmd:
|
||||
type: object
|
||||
required: [id]
|
||||
properties:
|
||||
id: { type: integer, format: int64 }
|
||||
|
||||
RegulatorInspNoticeExportCmd:
|
||||
type: object
|
||||
properties:
|
||||
ids:
|
||||
type: array
|
||||
items: { type: integer, format: int64 }
|
||||
scope: { type: string, enum: [SELECTED, FILTERED, ALL] }
|
||||
noticeNo: { type: string }
|
||||
orgId: { type: integer, format: int64 }
|
||||
orgName: { type: string }
|
||||
keyword: { type: string }
|
||||
inspTypeCode: { type: string }
|
||||
sourceTypeCode: { type: integer }
|
||||
sourceRefNo: { type: string }
|
||||
leaderName: { type: string }
|
||||
planInspTimeStart: { type: string }
|
||||
planInspTimeEnd: { type: string }
|
||||
confirmFlag: { type: integer }
|
||||
feedbackFlag: { type: integer }
|
||||
statusCode: { type: integer }
|
||||
|
||||
InstitutionInspNoticeMaterialUploadCmd:
|
||||
type: object
|
||||
required: [materialId, fileUrl]
|
||||
properties:
|
||||
materialId: { type: integer, format: int64 }
|
||||
fileUrl: { type: string }
|
||||
|
||||
InstitutionInspNoticeFeedbackCmd:
|
||||
type: object
|
||||
required: [id]
|
||||
properties:
|
||||
id: { type: integer, format: int64 }
|
||||
materials:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/InstitutionInspNoticeMaterialUploadCmd'
|
||||
|
||||
SingleResponseRegulatorInspNoticeCO:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/SingleResponseBase'
|
||||
- type: object
|
||||
properties:
|
||||
data: { $ref: '#/components/schemas/RegulatorInspNoticeCO' }
|
||||
|
||||
SingleResponseInstitutionInspNoticeCO:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/SingleResponseBase'
|
||||
- type: object
|
||||
properties:
|
||||
data: { $ref: '#/components/schemas/InstitutionInspNoticeCO' }
|
||||
|
||||
PageResponseRegulatorInspNoticeCO:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/SingleResponseBase'
|
||||
- type: object
|
||||
properties:
|
||||
data:
|
||||
type: array
|
||||
items: { $ref: '#/components/schemas/RegulatorInspNoticeCO' }
|
||||
total: { type: integer, format: int64 }
|
||||
|
||||
PageResponseInstitutionInspNoticeCO:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/SingleResponseBase'
|
||||
- type: object
|
||||
properties:
|
||||
data:
|
||||
type: array
|
||||
items: { $ref: '#/components/schemas/InstitutionInspNoticeCO' }
|
||||
total: { type: integer, format: int64 }
|
||||
|
||||
SingleResponseInspNoticeMaterialCO:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/SingleResponseBase'
|
||||
- type: object
|
||||
properties:
|
||||
data: { $ref: '#/components/schemas/InspNoticeMaterialCO' }
|
||||
|
||||
SingleResponseInspNoticeMaterialCOList:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/SingleResponseBase'
|
||||
- type: object
|
||||
properties:
|
||||
data:
|
||||
type: array
|
||||
items: { $ref: '#/components/schemas/InspNoticeMaterialCO' }
|
||||
|
||||
SingleResponseVoid:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/SingleResponseBase'
|
||||
- type: object
|
||||
properties:
|
||||
data: { nullable: true }
|
||||
|
|
@ -0,0 +1,510 @@
|
|||
openapi: 3.0.3
|
||||
info:
|
||||
title: 监管端-安评报告数据库 API
|
||||
description: |
|
||||
对齐监管端原型页 `mod-report-library`(安评报告数据库)。
|
||||
|
||||
## 原型能力对照
|
||||
| 原型 | 后端 |
|
||||
|------|------|
|
||||
| 近三年报告 / 本年度 | `GET /summary` |
|
||||
| 筛选:名称编号、报送机构、年度、评价类型、行业、报送时间起止 | `GET /page` |
|
||||
| 列表列:编号/名称/机构/类型/行业/签发日/报送时间 | `EvalReportLibraryCO`(含 `orgName`) |
|
||||
| 查看报告 | `GET /get`(`fileUrl`) |
|
||||
| AI分析 | **前端静态,无后端接口** |
|
||||
| 批量下载 / 导出目录 | `POST /batch-download`(ZIP)、`POST /export-catalog`(CSV) |
|
||||
| 补录历史报告 | `POST /add`(与机构端上传字段对齐,强制已报送) |
|
||||
| 抽查发起/复核(与机构端整改闭环,本页列表未直出按钮) | `/eval-report-spotcheck/**` |
|
||||
|
||||
与机构端关系:机构 `submit`/`archive`/`add(submitToRegulator)` → `submit_flag=1` 后进入监管库;监管抽查 → 机构整改 → 监管复核。
|
||||
|
||||
**Apifox 导入**:项目设置 → 导入数据 → OpenAPI → 选择本文件。
|
||||
|
||||
成功:`success=true` 且 `code="0"`(文件流接口直接返回附件,失败时返回 JSON)
|
||||
version: 1.1.0
|
||||
contact:
|
||||
name: safety-eval-service
|
||||
|
||||
servers:
|
||||
- url: http://localhost:8095
|
||||
description: 本地开发
|
||||
- url: http://192.168.20.100:30140
|
||||
description: 测试网关(100)
|
||||
|
||||
tags:
|
||||
- name: 监管端-安评报告库
|
||||
description: 报告数据库列表/详情/汇总/补录
|
||||
- name: 监管端-报告抽查
|
||||
description: 发起抽查与复核(机构整改闭环)
|
||||
|
||||
paths:
|
||||
/safetyEval/regulator/eval-report/summary:
|
||||
get:
|
||||
tags: [监管端-安评报告库]
|
||||
summary: 报告数据库页顶栏汇总
|
||||
operationId: regulatorEvalReportSummary
|
||||
responses:
|
||||
'200':
|
||||
description: 成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SingleResponseRegulatorEvalReportSummaryCO'
|
||||
example:
|
||||
success: true
|
||||
code: "0"
|
||||
data:
|
||||
recentThreeYearCount: 286
|
||||
currentYearCount: 92
|
||||
submittedTotalCount: 310
|
||||
|
||||
/safetyEval/regulator/eval-report/page:
|
||||
get:
|
||||
tags: [监管端-安评报告库]
|
||||
summary: 分页查询已报送报告
|
||||
description: 默认仅返回 `submitFlag=1`(机构已报送/归档入库)的报告。
|
||||
operationId: regulatorEvalReportPage
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/current'
|
||||
- $ref: '#/components/parameters/size'
|
||||
- name: keyword
|
||||
in: query
|
||||
description: 报告名称 / 编号
|
||||
schema: { type: string }
|
||||
- name: orgId
|
||||
in: query
|
||||
description: 机构 id(精确)
|
||||
schema: { type: integer, format: int64 }
|
||||
- name: orgName
|
||||
in: query
|
||||
description: 报送机构名称(模糊,按机构表 unitName 解析)
|
||||
schema: { type: string }
|
||||
- name: reportYear
|
||||
in: query
|
||||
schema: { type: integer, example: 2026 }
|
||||
- name: evalTypeCode
|
||||
in: query
|
||||
description: PRE / ACCEPT / STATUS
|
||||
schema: { type: string, example: PRE }
|
||||
- name: industryCode
|
||||
in: query
|
||||
schema: { type: string, example: HAZCHEM }
|
||||
- name: reportStatusCode
|
||||
in: query
|
||||
description: 1已入库 2抽查中 3待整改 4已复核
|
||||
schema: { type: integer }
|
||||
- name: archiveTimeStart
|
||||
in: query
|
||||
description: 报送时间起 yyyy-MM-dd
|
||||
schema: { type: string, example: '2026-01-01' }
|
||||
- name: archiveTimeEnd
|
||||
in: query
|
||||
description: 报送时间止 yyyy-MM-dd
|
||||
schema: { type: string, example: '2026-12-31' }
|
||||
- name: submitFlag
|
||||
in: query
|
||||
description: 默认 1;一般无需传
|
||||
schema: { type: integer, example: 1 }
|
||||
responses:
|
||||
'200':
|
||||
description: 成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/PageResponseEvalReportLibraryCO'
|
||||
|
||||
/safetyEval/regulator/eval-report/get:
|
||||
get:
|
||||
tags: [监管端-安评报告库]
|
||||
summary: 报告详情
|
||||
operationId: regulatorEvalReportGet
|
||||
parameters:
|
||||
- name: id
|
||||
in: query
|
||||
required: true
|
||||
schema: { type: string }
|
||||
responses:
|
||||
'200':
|
||||
description: 成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SingleResponseEvalReportLibraryCO'
|
||||
|
||||
/safetyEval/regulator/eval-report/add:
|
||||
post:
|
||||
tags: [监管端-安评报告库]
|
||||
summary: 补录历史报告
|
||||
description: |
|
||||
监管侧补录;`submitFlag` 固定为已报送。
|
||||
字段与机构端上传对齐(行业、被评价单位、签发日、页数、保密等)。
|
||||
文件先走统一上传拿 `fileUrl`。
|
||||
operationId: regulatorEvalReportAdd
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RegulatorEvalReportAddCmd'
|
||||
example:
|
||||
orgId: 10001
|
||||
reportNo: CQAP-2026-0715
|
||||
reportName: 华安化工园区安全预评价报告
|
||||
reportYear: 2026
|
||||
evalTypeCode: PRE
|
||||
evalTypeName: 安全预评价
|
||||
industryCode: HAZCHEM
|
||||
industryName: 危险化学品
|
||||
evaluatedUnitName: 重庆华安化工有限公司
|
||||
issueDate: '2026-07-15'
|
||||
pageCount: 186
|
||||
fileUrl: https://oss.example.com/reports/xxx.pdf
|
||||
fileName: 华安化工预评价.pdf
|
||||
secretLevelCode: NORMAL
|
||||
secretLevelName: 普通
|
||||
responses:
|
||||
'200':
|
||||
description: 成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SingleResponseEvalReportLibraryCO'
|
||||
|
||||
/safetyEval/regulator/eval-report/batch-download:
|
||||
post:
|
||||
tags: [监管端-安评报告库]
|
||||
summary: 批量下载报告文件(ZIP)
|
||||
description: |
|
||||
按勾选报告 ID 拉取各自 `fileUrl` 打包为 ZIP。
|
||||
上限 50 份;无有效文件地址时报错 06-07-012。
|
||||
成功直接返回 `application/zip` 附件流。
|
||||
operationId: regulatorEvalReportBatchDownload
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RegulatorEvalReportBatchDownloadCmd'
|
||||
example:
|
||||
ids: [10001, 10002, 10003]
|
||||
responses:
|
||||
'200':
|
||||
description: ZIP 文件流,或业务失败时的 JSON
|
||||
content:
|
||||
application/zip:
|
||||
schema:
|
||||
type: string
|
||||
format: binary
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SingleResponseBase'
|
||||
|
||||
/safetyEval/regulator/eval-report/export-catalog:
|
||||
post:
|
||||
tags: [监管端-安评报告库]
|
||||
summary: 导出报告目录(CSV)
|
||||
description: |
|
||||
导出「安评报告数据库目录」。
|
||||
- `ids` 非空或 `scope=SELECTED`:导出勾选
|
||||
- `scope=FILTERED`(默认无 ids):导出当前筛选结果
|
||||
- `scope=ALL`:导出全部已报送
|
||||
上限 5000 行;UTF-8 BOM,Excel 可直接打开。
|
||||
operationId: regulatorEvalReportExportCatalog
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RegulatorEvalReportExportCmd'
|
||||
example:
|
||||
scope: FILTERED
|
||||
reportYear: 2026
|
||||
industryCode: HAZCHEM
|
||||
responses:
|
||||
'200':
|
||||
description: CSV 文件流,或业务失败时的 JSON
|
||||
content:
|
||||
text/csv:
|
||||
schema:
|
||||
type: string
|
||||
format: binary
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SingleResponseBase'
|
||||
|
||||
/safetyEval/regulator/eval-report-spotcheck/start:
|
||||
post:
|
||||
tags: [监管端-报告抽查]
|
||||
summary: 发起抽查
|
||||
description: 报告须已入库(status=1);不合格须填整改要求,并消息通知机构。
|
||||
operationId: regulatorSpotcheckStart
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RegulatorSpotcheckStartCmd'
|
||||
example:
|
||||
reportId: 10001
|
||||
checkResultCode: 2
|
||||
checkResultName: 不合格
|
||||
checkOpinion: 危险辨识不完整
|
||||
rectifyRequire: 请补充重大危险源辨识章节并重新签章
|
||||
responses:
|
||||
'200':
|
||||
description: 成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SingleResponseEvalReportSpotcheckCO'
|
||||
|
||||
/safetyEval/regulator/eval-report-spotcheck/review:
|
||||
post:
|
||||
tags: [监管端-报告抽查]
|
||||
summary: 复核抽查
|
||||
operationId: regulatorSpotcheckReview
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RegulatorSpotcheckReviewCmd'
|
||||
example:
|
||||
spotcheckId: 20001
|
||||
reviewResultCode: 1
|
||||
reviewResultName: 通过
|
||||
responses:
|
||||
'200':
|
||||
description: 成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SingleResponseEvalReportSpotcheckCO'
|
||||
|
||||
/safetyEval/regulator/eval-report-spotcheck/list:
|
||||
get:
|
||||
tags: [监管端-报告抽查]
|
||||
summary: 按报告查询抽查记录
|
||||
operationId: regulatorSpotcheckList
|
||||
parameters:
|
||||
- name: reportId
|
||||
in: query
|
||||
required: true
|
||||
schema: { type: integer, format: int64 }
|
||||
responses:
|
||||
'200':
|
||||
description: 成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SingleResponseEvalReportSpotcheckCOList'
|
||||
|
||||
/safetyEval/regulator/eval-report-spotcheck/get:
|
||||
get:
|
||||
tags: [监管端-报告抽查]
|
||||
summary: 抽查详情
|
||||
operationId: regulatorSpotcheckGet
|
||||
parameters:
|
||||
- name: id
|
||||
in: query
|
||||
required: true
|
||||
schema: { type: string }
|
||||
responses:
|
||||
'200':
|
||||
description: 成功
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SingleResponseEvalReportSpotcheckCO'
|
||||
|
||||
components:
|
||||
parameters:
|
||||
current:
|
||||
name: current
|
||||
in: query
|
||||
schema: { type: integer, default: 1 }
|
||||
size:
|
||||
name: size
|
||||
in: query
|
||||
schema: { type: integer, default: 10 }
|
||||
|
||||
schemas:
|
||||
SingleResponseBase:
|
||||
type: object
|
||||
properties:
|
||||
success: { type: boolean, example: true }
|
||||
code: { type: string, example: "0" }
|
||||
message: { type: string }
|
||||
errCode: { type: string }
|
||||
errMessage: { type: string }
|
||||
|
||||
EvalReportLibraryCO:
|
||||
type: object
|
||||
properties:
|
||||
id: { type: string }
|
||||
orgId: { type: string }
|
||||
orgName: { type: string, description: 报送机构名称 }
|
||||
projectId: { type: string }
|
||||
customerId: { type: string }
|
||||
evaluatedUnitName: { type: string }
|
||||
reportNo: { type: string }
|
||||
reportName: { type: string }
|
||||
reportYear: { type: integer }
|
||||
evalTypeCode: { type: string }
|
||||
evalTypeName: { type: string }
|
||||
industryCode: { type: string }
|
||||
industryName: { type: string }
|
||||
fileUrl: { type: string }
|
||||
fileName: { type: string }
|
||||
submitFlag: { type: integer, description: "1已报送2未报送" }
|
||||
reportStatusCode: { type: integer }
|
||||
reportStatusName: { type: string }
|
||||
displayStatusName: { type: string }
|
||||
archiveTime: { type: string, format: date-time, description: 报送/入库时间 }
|
||||
issueDate: { type: string, format: date, description: 签发日期 }
|
||||
pageCount: { type: integer }
|
||||
secretLevelCode: { type: string }
|
||||
secretLevelName: { type: string }
|
||||
remarks: { type: string }
|
||||
|
||||
RegulatorEvalReportSummaryCO:
|
||||
type: object
|
||||
properties:
|
||||
recentThreeYearCount: { type: integer, format: int64 }
|
||||
currentYearCount: { type: integer, format: int64 }
|
||||
submittedTotalCount: { type: integer, format: int64 }
|
||||
|
||||
RegulatorEvalReportAddCmd:
|
||||
type: object
|
||||
required: [orgId, reportName, fileUrl]
|
||||
properties:
|
||||
orgId: { type: integer, format: int64 }
|
||||
projectId: { type: integer, format: int64 }
|
||||
reportName: { type: string }
|
||||
reportNo: { type: string }
|
||||
reportYear: { type: integer }
|
||||
evalTypeCode: { type: string }
|
||||
evalTypeName: { type: string }
|
||||
industryCode: { type: string }
|
||||
industryName: { type: string }
|
||||
evaluatedUnitName: { type: string }
|
||||
customerId: { type: integer, format: int64 }
|
||||
issueDate: { type: string, format: date }
|
||||
pageCount: { type: integer }
|
||||
businessScope: { type: string }
|
||||
fileUrl: { type: string }
|
||||
fileName: { type: string }
|
||||
secretLevelCode: { type: string }
|
||||
secretLevelName: { type: string }
|
||||
remarks: { type: string }
|
||||
|
||||
RegulatorEvalReportBatchDownloadCmd:
|
||||
type: object
|
||||
required: [ids]
|
||||
properties:
|
||||
ids:
|
||||
type: array
|
||||
items: { type: integer, format: int64 }
|
||||
maxItems: 50
|
||||
|
||||
RegulatorEvalReportExportCmd:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/RegulatorEvalReportPageQueryFields'
|
||||
- type: object
|
||||
properties:
|
||||
ids:
|
||||
type: array
|
||||
items: { type: integer, format: int64 }
|
||||
scope:
|
||||
type: string
|
||||
enum: [SELECTED, FILTERED, ALL]
|
||||
description: 有 ids 时默认 SELECTED;无 ids 默认 FILTERED
|
||||
|
||||
RegulatorEvalReportPageQueryFields:
|
||||
type: object
|
||||
properties:
|
||||
orgId: { type: integer, format: int64 }
|
||||
orgName: { type: string }
|
||||
keyword: { type: string }
|
||||
reportYear: { type: integer }
|
||||
evalTypeCode: { type: string }
|
||||
industryCode: { type: string }
|
||||
reportStatusCode: { type: integer }
|
||||
archiveTimeStart: { type: string }
|
||||
archiveTimeEnd: { type: string }
|
||||
submitFlag: { type: integer }
|
||||
|
||||
RegulatorSpotcheckStartCmd:
|
||||
type: object
|
||||
required: [reportId, checkResultCode]
|
||||
properties:
|
||||
reportId: { type: integer, format: int64 }
|
||||
checkResultCode: { type: integer, description: "1合格2不合格" }
|
||||
checkResultName: { type: string }
|
||||
checkOpinion: { type: string }
|
||||
rectifyRequire: { type: string, description: 不合格必填 }
|
||||
|
||||
RegulatorSpotcheckReviewCmd:
|
||||
type: object
|
||||
required: [spotcheckId, reviewResultCode]
|
||||
properties:
|
||||
spotcheckId: { type: integer, format: int64 }
|
||||
reviewResultCode: { type: integer, description: "1通过2不通过" }
|
||||
reviewResultName: { type: string }
|
||||
|
||||
EvalReportSpotcheckCO:
|
||||
type: object
|
||||
properties:
|
||||
id: { type: string }
|
||||
orgId: { type: string }
|
||||
reportId: { type: string }
|
||||
checkResultCode: { type: integer }
|
||||
checkResultName: { type: string }
|
||||
checkOpinion: { type: string }
|
||||
rectifyRequire: { type: string }
|
||||
rectifyFeedback: { type: string }
|
||||
reviewResultCode: { type: integer }
|
||||
reviewResultName: { type: string }
|
||||
checkerId: { type: string }
|
||||
checkerName: { type: string }
|
||||
checkTime: { type: string, format: date-time }
|
||||
|
||||
SingleResponseEvalReportLibraryCO:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/SingleResponseBase'
|
||||
- type: object
|
||||
properties:
|
||||
data: { $ref: '#/components/schemas/EvalReportLibraryCO' }
|
||||
|
||||
SingleResponseRegulatorEvalReportSummaryCO:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/SingleResponseBase'
|
||||
- type: object
|
||||
properties:
|
||||
data: { $ref: '#/components/schemas/RegulatorEvalReportSummaryCO' }
|
||||
|
||||
PageResponseEvalReportLibraryCO:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/SingleResponseBase'
|
||||
- type: object
|
||||
properties:
|
||||
data:
|
||||
type: array
|
||||
items: { $ref: '#/components/schemas/EvalReportLibraryCO' }
|
||||
total: { type: integer, format: int64 }
|
||||
|
||||
SingleResponseEvalReportSpotcheckCO:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/SingleResponseBase'
|
||||
- type: object
|
||||
properties:
|
||||
data: { $ref: '#/components/schemas/EvalReportSpotcheckCO' }
|
||||
|
||||
SingleResponseEvalReportSpotcheckCOList:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/SingleResponseBase'
|
||||
- type: object
|
||||
properties:
|
||||
data:
|
||||
type: array
|
||||
items: { $ref: '#/components/schemas/EvalReportSpotcheckCO' }
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
量','30%','抽查合格率、退回修改次数'],['风险处置','20%','未闭环预警、逾期反馈'],['监督检查','20%','检查结论、整改完成情况']]);
|
||||
} else if (type === 'inspectionCreate') {
|
||||
title.textContent = name;
|
||||
html = section('告知信息', '告知下发后同步至机构端消息中心,机构需确认检查时间并按要求准备材料。') + '<div class="form-grid"><div class="field"><label>评价机构</label><select><option>重庆安评技术研究院有限公司</option><option>重庆恒安安全评价有限公司</option><option>重庆渝安风险评估中心</option></select></div><div class="field"><label>检查类型</label><select><option>项目过程检查</option><option>资质保持检查</option><option>专项检查</option></select></div><div class="field"><label>计划检查时间</label><input type="datetime-local" value="2026-07-25T09:00"></div><div class="field"><label>来源预警</label><select><option>无</option><option>W-PROJ-2026-021</option><option>W-QUAL-2026-012</option></select></div><div class="field full"><label>检查事项</label><textarea>请准备项目过程记录、人员到场记录及相关证明材料。</textarea></div><div class="field full"><label>告知附件</label><input type="file" accept=".pdf,.doc,.docx"></div></div>';
|
||||
foot += actionButton('下发机构', '监督检查告知已下发');
|
||||
} else if (type === 'inspectionResult') {
|
||||
title.textContent = '登记监督检查结果 - ' + name;
|
||||
html = section('检查结果', '记录实际检查情况、不符合项、整改要求和后续处置。') + '<div class="form-grid"><div class="field"><label>实际检查时间</label><input type="datetime-local" value="2026-07-22T09:30"></div><div class="field"><label>检查结论</label><select><option>未发现问题</option><option>责令整改</option><option>转入风险预警</option></select></div><div class="field full"><label>检查情况</label><textarea placeholder="填写现场检查情况和发现问题"></textarea></div><div class="field full"><label>整改要求</label><textarea placeholder="需要整改时填写整改事项和期限"></textarea></div><div class="field"><label>整改期限</label><input type="date" value="2026-08-05"></div><div class="field full"><label>检查记录附件</label><input type="file" multiple accept=".pdf,.doc,.docx,.jpg,.jpeg,.png"></div></div>';
|
||||
foot += actionButton('提交检查结果', '监督检查结果已登记'); } else if (type === 'inspectionDetail') {
|
||||
title.textContent = '监督检查告知 - ' + name;
|
||||
html = section('告知详情', '展示告知内容、机构确认和材料反馈情况。') + tableHtml(['事项','内容','状态'], [['检查时间','2026-07-22 09:30','机构已确认'],['检查类型','项目过程检查','已下发'],['来源预警','现场勘查异常','已关联'],['机构反馈','联系人及准备材料清单','已反馈']]) + '<div class="form-grid" style="margin-top:1rem;"><div class="field full"><label>监管备注</label><textarea placeholder="填写检查前备注或补充要求"></textarea></div></div>';
|
||||
foot += actionButton('保存备注', '检查备注已保存');
|
||||
} else if (type === 'trainingCourseCreate' || type === 'trainingCourseEdit') {
|
||||
title.textContent = type === 'trainingCourseCreate' ? '新增培训课程' : '编辑课程 - ' + name;
|
||||
html = '<div class="form-grid"><div class="field full"><label>课程名称</label><input value="' + (type === 'trainingCourseEdit' ? name : '') + '" placeholder="输入课程名称"></div><div class="field"><label>课程分类</label><select><option>法律法规</option><option>专业能力</option><option>过程控制</option></select></div><div class="field"><label>课程学时</label><input type="number" min="1" value="4"></div><div class="field"><label>适用人员</label><select><option>全体评价人员</option><option>机构负责人</option><option>技术负责人</option><option>过程控制负责人</option></select></div><div class="field"><label>考试要求</label><select><option>需要考试</option><option>无需考试</option></select></div><div class="field full"><label>课程课件</label><input type="file" multiple accept=".pdf,.ppt,.pptx,.mp4"></div><div class="field full"><label>课程简介</label><textarea placeholder="填写课程目标和主要内容"></textarea></div></div>';
|
||||
foot += actionButton(type === 'trainingCourseCreate' ? '保存课程' : '保存修改', '课程信息已保存');
|
||||
} else if (type === 'trainingTaskCreate') {
|
||||
title.textContent = name;
|
||||
html = '<div class="form-grid"><div class="field full"><label>任务名称</label><input placeholder="例如:2026年度安全评价专业培训"></div><div class="field"><label>选择课程</label><select><option>安全评价通则与责任要求</option><option>评价机构过程控制实务</option></select></div><div class="field"><label>下发范围</label><select><option>全市备案评价人员</option><option>机构负责人</option><option>过程控制负责人</option></select></div><div class="field"><label>完成期限</label><input type="date" value="2026-09-30"></div><div class="field"><label>逾期提醒</label><select><option>提前7天</option><option>提前3天</option><option>不提醒</option></select></div><div class="field full"><label>任务说明</label><textarea placeholder="填写培训要求"></textarea></div></div>';
|
||||
foot += actionButton('确认下发', '培训任务已下发');
|
||||
} else if (type === 'trainingStudents') {
|
||||
title.textContent = '班级学员列表 - ' + name;
|
||||
html = section('学员完成情况', '查看班级学员的学习进度、完成学时和考试结果。') + tableHtml(['姓名','所属机构','部门','完成进度','考试结果'], [['张建国','重庆安评技术研究院有限公司','评价一部','100%','92分/合格'],['李明华','重庆恒安安全评价有限公司','评价二部','80%','待考试'],['王海','重庆渝安风险评估中心','过程控制部','60%','未完成']]);
|
||||
foot += actionButton('导出学员名单', '班级学员名单已生成');
|
||||
} else if (type === 'trainingCourses') {
|
||||
title.textContent = '班级课程列表 - ' + name;
|
||||
html = section('课程配置', '展示班级包含的必修课程、学时和考试要求。') + tableHtml(['课程名称','培训类型','学时','学习要求'], [['安全生产举报和奖励办法','法律法规','0.7','必修/考试'],['安全评价过程控制实务','专业能力','1.0','必修/考试'],['典型事故案例警示教育','事故警示','0.3','必修/无需考试']]);
|
||||
foot += actionButton('导出课程清单', '班级课程清单已生成');
|
||||
} else if (type === 'trainingExtend') {
|
||||
title.textContent = '培训班级延期 - ' + name;
|
||||
html = '<div class="form-grid"><div class="field"><label>原结束时间</label><input value="2026-06-30" disabled></div><div class="field"><label>延期至</label><input type="date" value="2026-07-15"></div><div class="field full"><label>延期原因</label><textarea placeholder="填写延期原因"></textarea></div><div class="field full"><label>通知方式</label><label><input type="checkbox" checked> 通知参训单位</label><label><input type="checkbox" checked> 通知未完成学员</label></div></div>';
|
||||
foot += actionButton('确认延期', '培训班级结束时间已更新');
|
||||
} else if (type === 'trainingQr') {
|
||||
title.textContent = '班级二维码 - ' + name;
|
||||
html = section('扫码参训', '学员扫码后进入班级课程,二维码有效期与班级结束时间一致。') + '<div style="width:180px;height:180px;margin:1rem auto;background:repeating-conic-gradient(#111 0 25%,#fff 0 50%) 0/18px 18px;border:12px solid #fff;box-shadow:0 0 0 1px #d1d5db"></div><p style="text-align:center;color:var(--color-text-se
|
||||
|
|
@ -0,0 +1,190 @@
|
|||
id="mod-reg-message">
|
||||
<div class="page-header"><div><h2>📄 监督检查通知</h2><div style="font-size:.82rem;color:var(--color-text-secondary);margin-top:.2rem;">接收监管端下发的整改通知、监督检查通知、核查函及其他通知文件,机构在线反馈结果、上传证明材料并查看监管复核意见。</div></div><div class="boss-tabs"><button class="boss-tab active" onclick="switchBossTab(this,'msg-all')">全部通知</button><button class="boss-tab" onclick="switchBossTab(this,'msg-unread')">待处理</button><button class="boss-tab" onclick="switchBossTab(this,'msg-processing')">处理中</button><button class="boss-tab" onclick="switchBossTab(this,'msg-feedback')">待监管复核</button><button class="boss-tab" onclick="switchBossTab(this,'msg-closed')">已办结</button></div></div>
|
||||
<div class="boss-grid cols-4" style="margin-bottom:1rem;"><div class="boss-card boss-metric"><div><div class="label">监管消息总数</div><div class="value">9</div><div class="hint">来源:监管端风险预警中心</div></div><div class="icon">✉️</div></div><div class="boss-card boss-metric"><div><div class="label">待处理</div><div class="value boss-kpi-danger">3</div><div class="hint">需机构直接处理</div></div><div class="icon">待</div></div><div class="boss-card boss-metric"><div><div class="label">待监管复核</div><div class="value boss-kpi-warning">2</div><div class="hint">材料已提交</div></div><div class="icon">审</div></div><div class="boss-card boss-metric"><div><div class="label">已办结</div><div class="value boss-kpi-success">4</div><div class="hint">办结消息可归档</div></div><div class="icon">结</div></div></div>
|
||||
<div class="boss-note"><strong>消息来源:</strong>监管端风险预警中心。监管人员在风险预警中心发出整改通知、核查函、补正通知或办结结果后,机构端在此接收并处理;资质保持监控页面只作为监管信息来源。</div>
|
||||
<div class="search-form"><div class="row"><div class="field"><label>通知关键词</label><input type="text" data-filter-input="msg-q" placeholder="通知编号/预警编号/事项"></div><div class="field"><label>通知类型</label><select data-filter-input="msg-type"><option value="">全部</option><option>整改通知</option><option>核查函</option><option>补正通知</option><option>办结通知</option></select></div><div class="field"><label>处理状态</label><select data-filter-input="msg-state"><option value="">全部</option><option value="unread">待处理</option><option value="processing">处理中</option><option value="feedback">待监管复核</option><option value="closed">已办结</option></select></div><div class="actions"><button class="btn btn-primary" onclick="filterBossRows('reg-message-table')">🔍 搜索</button><button class="btn btn-ghost" onclick="resetBossFilters('mod-reg-message')">↺ 重置</button></div></div></div>
|
||||
<div class="boss-toolbar"><div class="left"><span style="font-size:.85rem;color:var(--color-text-secondary);">监管消息列表:展示来源预警、来源字段、办理期限和机构处理状态。</span></div><div class="right"><button class="btn btn-ghost btn-sm" onclick="openBossModal('regMessageExport','监管消息清单')">导出消息</button></div></div>
|
||||
<div class="data-table"><table id="reg-message-table"><thead><tr><th style="width:34px"><input type="checkbox" onclick="toggleBossChecks(this,'reg-message-table')"></th><th>通知编号</th><th>通知类型</th><th>来源预警</th><th>来源字段</th><th>监管要求</th><th>办理期限</th><th>状态</th><th style="width:90px;text-align:center;">操作</th></tr></thead><tbody>
|
||||
<tr data-keywords="M-QUAL-2026-012 W-QUAL-2026-012 整改通知 资质保持 unread 待处理 重庆渝安" data-state="unread"><td><input type="checkbox"></td><td>M-QUAL-2026-012</td><td><span class="tag tag-danger">整改通知</span></td><td>W-QUAL-2026-012</td><td><div class="source-list"><span class="source-pill">固定资产</span><span class="source-pill">工作场所</span><span class="source-pill">专职人数</span></div></td><td>补充固定资产、场所面积、档案室面积和专职人员证明材料。</td><td>2026-07-25</td><td><span class="tag tag-danger" data-msg-status>待处理</span></td><td class="action-btns" style="justify-content:center;"><button class="btn btn-primary btn-sm" onclick="openBossModal('regMessageProcess','M-QUAL-2026-012')">处理</button></td></tr>
|
||||
<tr data-keywords="M-QUAL-2026-011 W-QUAL-2026-011 整改通知 资质保持 processing 处理中 重庆恒安" data-state="processing"><td><input type="checkbox"></td><td>M-QUAL-2026-011</td><td><span class="tag tag-warning">整改通知</span></td><td>W-QUAL-2026-011</td><td><div class="source-list"><span class="source-pill">职称等级</span><span class="source-pill">注册安全工程师比例</span><span class="source-pill">业务范围数量</span></div></td><td>提交高级职称人员补充计划、劳动合同和社保清单。</td><td>2026-07-22</td><td><span class="tag tag-warning" data-msg-status>处理中</span></td><td class="action-btns" style="justify-content:center;"><button class="btn btn-primary btn-sm" onclick="openBossModal('regMessageProcess','M-QUAL-2026-011')">处理</button></td></tr>
|
||||
<tr data-keywords="M-QUAL-2026-013 W-QUAL-2026-013 属地核验 feedback 待监管复核 北京中安" data-state="feedback"><td><input type="checkbox"></td><td>M-QUAL-2026-013</td><td><span class="tag tag-info">属地核验</span></td><td>W-QUAL-2026-013</td><td><div class="source-list"><span class="source-pill">本市社保人数</span><span class="source-pill">租赁合同</span><span class="source-pill">注册地</span></div></td><td>已提交重庆场所、社保人员和档案室说明,等待监管复核。</td><td>2026-07-20</td><td><span class="tag tag-info" data-msg-status>待监管复核</span></td><td class="action-btns" style="justify-content:center;"><button class="btn btn-primary btn-sm" onclick="openBossModal('regMessageProcess','M-QUAL-2026-013')">处理</button></td></tr>
|
||||
<tr data-keywords="M-QUAL-2026-010 W-QUAL-2026-010 补正通知 returned processing 监管退回" data-state="processing"><td><input type="checkbox"></td><td>M-QUAL-2026-010</td><td><span class="tag tag-warning">补正通知</span></td><td>W-QUAL-2026-010</td><td><div class="source-list"><span class="source-pill">证书附件</span><span class="source-pill">社保清单</span></div></td><td>监管退回:证书延续材料缺少发证机关页,请补充后再次提交。</td><td>2026-07-18</td><td><span class="tag tag-warning" data-msg-status>监管退回</span></td><td class="action-btns" style="justify-content:center;"><button class="btn btn-primary btn-sm" onclick="openBossModal('regMessageProcess','M-QUAL-2026-010')">处理</button></td></tr>
|
||||
<tr data-keywords="M-QUAL-2026-009 W-QUAL-2026-009 办结通知 closed 已办结" data-state="closed"><td><input type="checkbox"></td><td>M-QUAL-2026-009</td><td><span class="tag tag-success">办结通知</span></td><td>W-QUAL-2026-009</td><td><div class="source-list"><span class="source-pill">整改说明</span><span class="source-pill">复核结论</span></div></td><td>监管已确认整改材料,预警闭环,办结结果归档。</td><td>2026-07-12</td><td><span class="tag tag-success" data-msg-status>已办结</span></td><td class="action-btns" style="justify-content:center;"><button class="btn btn-primary btn-sm" onclick="openBossModal('regMessageProcess','M-QUAL-2026-009')">处理</button></td></tr>
|
||||
</tbody></table></div>
|
||||
</div> </main>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 模态框: 资质备案申请向导(5步) -->
|
||||
<div class="modal-overlay" id="modal-filing-guide">
|
||||
<div class="modal" style="width:800px;">
|
||||
<div class="modal-header"><h3>📋 资质备案申请</h3><button class="modal-close" onclick="closeModal('modal-filing-guide')">✕</button></div>
|
||||
<div class="modal-body">
|
||||
<div class="step-indicator" style="margin-bottom:1.5rem;">
|
||||
<div class="step active" id="step1-label"><span class="num" id="step1-num">1</span> 备案基本信息</div>
|
||||
<span class="connector"></span>
|
||||
<div class="step" id="step2-label"><span class="num" id="step2-num">2</span> 申请材料清单</div>
|
||||
<span class="connector"></span>
|
||||
<div class="step" id="step3-label"><span class="num" id="step3-num">3</span> 法定代表人承诺书</div>
|
||||
<span class="connector"></span>
|
||||
<div class="step" id="step4-label"><span class="num" id="step4-num">4</span> 备案人员管理</div>
|
||||
<span class="connector"></span>
|
||||
<div class="step" id="step5-label"><span class="num" id="step5-num">5</span> 装备清单</div>
|
||||
</div>
|
||||
<div class="step-content" id="step1-content">
|
||||
<h4 style="margin-bottom:1rem;">备案基本信息</h4>
|
||||
<div class="form-grid">
|
||||
<div class="field"><label>备案属地 <span style="color:red">*</span></label><select><option>重庆市渝北区</option><option>重庆市南岸区</option><option>重庆市江北区</option></select></div>
|
||||
<div class="field"><label>备案单位类型</label><select><option>本地单位</option><option>异地单位</option></select></div>
|
||||
<div class="field full"><label>备案单位</label><input type="text" value="重庆安评技术研究院有限公司"></div>
|
||||
<div class="field full"><label>单位基本情况介绍</label><textarea rows="4" placeholder="请输入单位基本情况介绍...">重庆安评技术研究院成立于2015年,是一家专业从事安全评价、安全咨询、安全技术开发与转让的综合性安全技术服务机构...</textarea></div>
|
||||
<div class="field full"><label>附件上传(支持PDF格式)</label><button class="btn btn-ghost btn-sm" onclick="alert('选择文件上传')">📎 上传文件</button></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="step-content" id="step2-content" style="display:none;">
|
||||
<h4 style="margin-bottom:1rem;">申请材料清单</h4>
|
||||
<div class="data-table" style="box-shadow:none;border:1px solid var(--color-border);">
|
||||
<table>
|
||||
<thead><tr><th style="width:30px"><input type="checkbox"></th><th>材料名称</th><th>是否必需</th><th>状态</th><th>操作</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td><input type="checkbox" checked></td><td>安全评价机构资质申请书</td><td><span class="tag tag-danger">必需</span></td><td><span class="tag tag-success">已上传</span></td><td><button class="btn btn-ghost btn-sm">预览</button></td></tr>
|
||||
<tr><td><input type="checkbox" checked></td><td>法人营业执照副本</td><td><span class="tag tag-danger">必需</span></td><td><span class="tag tag-success">已上传</span></td><td><button class="btn btn-ghost btn-sm">预览</button></td></tr>
|
||||
<tr><td><input type="checkbox" checked></td><td>技术人员资质证书</td><td><span class="tag tag-danger">必需</span></td><td><span class="tag tag-success">已上传</span></td><td><button class="btn btn-ghost btn-sm">预览</button></td></tr>
|
||||
<tr><td><input type="checkbox" checked></td><td>社保缴纳证明材料</td><td><span class="tag tag-danger">必需</span></td><td><span class="tag tag-warning">待上传</span></td><td><button class="btn btn-ghost btn-sm">📎 上传</button></td></tr>
|
||||
<tr><td><input type="checkbox"></td><td>办公场所证明材料</td><td><span class="tag tag-info">建议</span></td><td>—</td><td><button class="btn btn-ghost btn-sm">📎 上传</button></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="step-content" id="step3-content" style="display:none;">
|
||||
<h4 style="margin-bottom:1rem;">申请单位法定代表人承诺书</h4>
|
||||
<div style="border:1px solid var(--color-border);border-radius:var(--radius);padding:1rem;background:#fafafa;margin-bottom:1rem;">
|
||||
<p style="font-size:.85rem;line-height:1.8;">本申请人自愿申请安全评价机构资质备案,郑重承诺如下:<br><br>一、本申请人所提交的全部申请材料真实、准确、完整,无隐瞒、虚假陈述或重大遗漏;<br>二、本申请人符合《安全评价机构管理规定》等法律法规规定的资质条件;<br>三、本申请人将严格遵守国家有关安全生产的法律法规和技术标准;<br>四、本申请人愿意接受并配合监管部门的监督检查和评审工作。<br><br>如有违反上述承诺,本申请人愿意承担相应的法律责任。</p>
|
||||
</div>
|
||||
<div class="form-grid">
|
||||
<div class="field"><label>法定代表人</label><input type="text" value="刘强"></div>
|
||||
<div class="field"><label>签署日期</label><input type="date" value="2026-06-25"></div>
|
||||
<div class="field full"><label>电子签名</label><div style="border:1px dashed var(--color-border);border-radius:var(--radius);padding:1rem;text-align:center;color:var(--color-text-secondary);">点击此处绘制电子签名</div></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="step-content" id="step4-content" style="display:none;">
|
||||
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:.75rem;">
|
||||
<h4>备案人员信息</h4>
|
||||
<button class="btn btn-primary btn-sm" onclick="openModal('modal-filing-person-add')">➕ 添加人员信息</button>
|
||||
</div>
|
||||
<div class="data-table" style="box-shadow:none;border:1px solid var(--color-border);">
|
||||
<table>
|
||||
<thead><tr><th style="width:50px">序号</th><th>人员姓名</th><th>类型</th><th>职务</th><th>职称</th><th style="width:150px">操作</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>1</td><td>张建国</td><td>评价师</td><td>高级评价师</td><td>高级工程师</td><td class="action-btns"><button class="btn btn-ghost btn-sm">查看</button><button class="btn btn-ghost btn-sm">修改</button></td></tr>
|
||||
<tr><td>2</td><td>李明华</td><td>评价师</td><td>评价师</td><td>工程师</td><td class="action-btns"><button class="btn btn-ghost btn-sm">查看</button><button class="btn btn-ghost btn-sm">修改</button></td></tr>
|
||||
<tr><td>3</td><td>王丽萍</td><td>管理人员</td><td>人事主管</td><td>—</td><td class="action-btns"><button class="btn btn-ghost btn-sm">查看</button><button class="btn btn-ghost btn-sm">修改</button></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="step-content" id="step5-content" style="display:none;">
|
||||
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:.75rem;">
|
||||
<h4>申请单位装备清单</h4>
|
||||
<button class="btn btn-ghost btn-sm" onclick="alert('弹出企业已有设备列表,选择本次备案设备')">➕ 添加设备</button>
|
||||
</div>
|
||||
<div class="data-table" style="box-shadow:none;border:1px solid var(--color-border);margin-top:.5rem;">
|
||||
<table>
|
||||
<thead><tr><th style="width:50px">序号</th><th>装备名称</th><th>规格型号</th><th>生产厂家</th><th>计量检定情况</th><th>操作</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>1</td><td>气相色谱仪</td><td>GC-2018</td><td>岛津</td><td><button class="btn btn-ghost btn-sm">📎 上传报告</button></td><td><button class="btn btn-ghost btn-sm" onclick="alert('移除设备')">移除</button></td></tr>
|
||||
<tr><td>2</td><td>噪声计</td><td>HS-6288</td><td>杭州爱华</td><td><button class="btn btn-ghost btn-sm">📎 上传报告</button></td><td><button class="btn btn-ghost btn-sm">移除</button></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer" style="justify-content:space-between;">
|
||||
<div>
|
||||
<button class="btn btn-ghost" onclick="closeModal('modal-filing-guide')">取消</button>
|
||||
<button class="btn btn-ghost" onclick="alert('已暂存')">💾 暂存</button>
|
||||
</div>
|
||||
<div>
|
||||
<button class="btn btn-ghost" id="prev-step-btn" style="display:none;" onclick="prevStep()">← 上一步</button>
|
||||
<button class="btn btn-primary" id="next-step-btn" onclick="nextStep()">下一步 →</button>
|
||||
<button class="btn btn-primary" id="submit-step-btn" style="display:none;" onclick="submitFiling()">📤 提交备案</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 模态框: 添加备案人员信息 -->
|
||||
<div class="modal-overlay" id="modal-filing-person-add">
|
||||
<div class="modal" style="width:700px;">
|
||||
<div class="modal-header"><h3>➕ 添加备案人员</h3><button class="modal-close" onclick="closeModal('modal-filing-person-add')">✕</button></div>
|
||||
<div class="modal-body">
|
||||
<div class="form-grid">
|
||||
<div class="field"><label>人员类型</label><select><option>专职评价师</option><option>基础人员</option></select></div>
|
||||
<div class="field"><label>资质范围</label><select><option>矿山开采业</option><option>危险化学品行业</option><option>烟花爆竹行业</option><option>金属冶炼与加工</option></select></div>
|
||||
<div class="field"><label>姓名</label><input type="text" placeholder="人员姓名"></div>
|
||||
<div class="field"><label>性别</label><select><option>男</option><option>女</option></select></div>
|
||||
<div class="field"><label>出生日期</label><input type="date"></div>
|
||||
<div class="field"><label>身份证号</label><input type="text" placeholder="18位身份证号"></div>
|
||||
<div class="field"><label>学历</label><select><option>全日制 · 专科</option><option>全日制 · 本科</option><option>全日制 · 硕士</option><option>全日制 · 博士</option><option>在职教育 · 本科</option></select></div>
|
||||
<div class="field"><label>毕业院校</label><input type="text" placeholder="毕业院校"></div>
|
||||
<div class="field"><label>专业</label><input type="text" placeholder="所学专业"></div>
|
||||
<div class="field"><label>职务</label><input type="text" placeholder="职务"></div>
|
||||
<div class="field full"><label>现住地址</label><input type="text" placeholder="现住地址"></div>
|
||||
<div class="field full"><label>办公地址</label><input type="text" value="重庆市渝北区龙山街道100号"></div>
|
||||
<div class="field full"><label>出版学术专著、专利、科技发明等情况</label><textarea rows="2" placeholder="请描述"></textarea></div>
|
||||
<div class="field full"><label>自我申报的专业能力及认定方式</label><textarea rows="2" placeholder="请描述"></textarea></div>
|
||||
<div class="field full"><label>申报专业能力证明材料</label><button class="btn btn-ghost btn-sm" onclick="alert('上传附件')">📎 上传附件</button></div>
|
||||
<div class="field full"><label>主要学习工作经历</label><textarea rows="2" placeholder="请描述学习工作经历"></textarea></div>
|
||||
<div class="field"><label>职业资格等级及证书编号</label><input type="text" placeholder="如:一级/12345"></div>
|
||||
<div class="field"><label>是否注册安全工程师</label><select><option>是</option><option>否</option></select></div>
|
||||
<div class="field full"><label>电子签名</label><div style="border:1px dashed var(--color-border);border-radius:var(--radius);padding:.75rem 1rem;text-align:center;"><span style="color:#94a3b8;">未签名</span> <span style="font-size:0.75rem;color:var(--color-text-secondary);margin-left:0.3rem;">(点击进行签字)</span></div></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-ghost" onclick="closeModal('modal-filing-person-add')">取消</button>
|
||||
<button class="btn btn-primary" onclick="closeModal('modal-filing-person-add');alert('备案人员信息已添加!')">保存</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 模态框: 备案确认(5步向导-复用) -->
|
||||
<div class="modal-overlay" id="modal-filing-confirm">
|
||||
<div class="modal" style="width:800px;">
|
||||
<div class="modal-header"><h3>✅ 备案确认</h3><button class="modal-close" onclick="closeModal('modal-filing-confirm')">✕</button></div>
|
||||
<div class="modal-body">
|
||||
<div class="step-indicator" style="margin-bottom:1.5rem;">
|
||||
<div class="step active"><span class="num">1</span> 备案基本信息</div>
|
||||
<span class="connector"></span>
|
||||
<div class="step"><span class="num">2</span> 申请材料清单</div>
|
||||
<span class="connector"></span>
|
||||
<div class="step"><span class="num">3</span> 法定代表人承诺书</div>
|
||||
<span class="connector"></span>
|
||||
<div class="step"><span class="num">4</span> 备案人员管理</div>
|
||||
<span class="connector"></span>
|
||||
<div class="step"><span class="num">5</span> 装备清单</div>
|
||||
</div>
|
||||
<div class="form-grid">
|
||||
<div class="field"><label>备案属地</label><select><option>重庆市渝北区</option></select></div>
|
||||
<div class="field"><label>备案单位类型</label><select><option>本地单位</option></select></div>
|
||||
<div class="field"><label>上次备案时间</label><input type="date" value="2026-01-15"></div>
|
||||
<div class="field full"><label>备案单位</label><input type="text" value="重庆安评技术研究院有限公司"></div>
|
||||
<div class="field full"><label>单位基本情况介绍</label><textarea rows="3" placeholder="单位基本情况...">重庆安评技术研究院成立于2015年...</textarea></div>
|
||||
<div class="field full"><label>附件上传</label><button class="btn btn-ghost btn-sm">📎 上传文件</button></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer" style="justify-content:space-between;">
|
||||
<div><button class="btn btn-ghost" onclick="closeModal('modal-filing-confirm')">取消</button></div>
|
||||
<div><button class="btn btn-ghost">← 上一步</button><button class="btn btn-primary">下一步 →</button></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 模态框: 备案变更历史 -->
|
||||
<div class="modal-overlay" id="modal-filing-change-history">
|
||||
<div class="modal" style="width:560px;">
|
||||
<div class="modal-header"><h3>📋 备案变更记录</h3><button class="modal-close" onclick="closeModal('modal-filing-change-history')">✕</button></div>
|
||||
<div class="modal-body">
|
||||
<div class="data-table" style="box-shadow:none;border:1px solid var(--color-border);">
|
||||
<table><thead><tr><th style="width:50px">序号</th><th>变更事项</th><th>变更时间</th><th>操作人</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>1</td><td><span cla
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
id="mod-inspection-notice">
|
||||
<div class="page-header"><div><h2>📨 监督检查告知</h2><p class="reg-sub">根据风险预警、年度计划或专项安排下发检查告知,跟踪机构确认、材料反馈和检查结果。</p></div><button class="btn btn-primary" onclick="openRegModal('inspectionCreate','新建监督检查告知')">新建检查告知</button></div>
|
||||
<div class="search-form"><div class="row">
|
||||
<div class="field"><label>告知编号</label><input data-inspection-filter="number" placeholder="输入告知编号"></div>
|
||||
<div class="field"><label>评价机构</label><input data-inspection-filter="institution" placeholder="输入机构名称"></div>
|
||||
<div class="field"><label>检查类型</label><select data-inspection-filter="type"><option value="">全部</option><option>项目过程检查</option><option>资质保持检查</option><option>专项检查</option></select></div>
|
||||
<div class="field"><label>来源方式</label><select data-inspection-filter="source"><option value="">全部</option><option>风险预警</option><option>年度计划</option><option>专项安排</option></select></div>
|
||||
<div class="field"><label>来源预警编号</label><input data-inspection-filter="warning" placeholder="输入预警编号"></div>
|
||||
<div class="field"><label>检查负责人</label><input data-inspection-filter="leader" placeholder="输入负责人姓名"></div>
|
||||
<div class="field"><label>检查时间起</label><input type="date" data-inspection-filter="start"></div>
|
||||
<div class="field"><label>检查时间止</label><input type="date" data-inspection-filter="end"></div>
|
||||
<div class="field"><label>机构确认</label><select data-inspection-filter="confirm"><option value="">全部</option><option>未确认</option><option>已确认</option></select></div>
|
||||
<div class="field"><label>材料反馈</label><select data-inspection-filter="feedback"><option value="">全部</option><option>未提交</option><option>已提交</option></select></div>
|
||||
<div class="field"><label>办理状态</label><select data-inspection-filter="status"><option value="">全部</option><option>待下发</option><option>已下发</option><option>已反馈</option><option>已完成</option></select></div>
|
||||
<div class="actions"><button class="btn btn-primary" onclick="filterInspectionNotices()">🔍 搜索</button><button class="btn btn-ghost" onclick="resetInspectionNotices()">↺ 重置</button></div>
|
||||
</div></div>
|
||||
<div class="toolbar"><div class="left"><span class="total">共 4 条检查告知</span></div><div class="right"><button class="btn btn-ghost btn-sm" onclick="openRegModal('export','监督检查告知台账')">导出台账</button></div></div>
|
||||
<div class="data-table"><table id="inspection-notice-table"><thead><tr><th>告知编号</th><th>评价机构</th><th>检查类型</th><th>计划检查时间</th><th>来源</th><th>检查负责人</th><th>机构确认</th><th>材料反馈</th><th>办理状态</th><th>操作</th></tr></thead><tbody>
|
||||
<tr data-number="JC-2026-021" data-institution="重庆安评技术研究院有限公司" data-type="专项检查" data-source="年度计划" data-warning="" data-leader="周强" data-date="2026-08-05" data-confirm="未确认" data-feedback="未提交" data-status="待下发"><td>JC-2026-021</td><td>重庆安评技术研究院有限公司</td><td>专项检查</td><td>2026-08-05 09:00</td><td>年度计划</td><td>周强</td><td><span class="tag tag-warning">未确认</span></td><td>未提交</td><td><span class="tag tag-warning">待下发</span></td><td><button class="btn btn-primary btn-sm" onclick="openRegModal('inspectionCreate','编辑 JC-2026-021')">编辑</button> <button class="btn btn-ghost btn-sm" onclick="updateInspectionStatus(this,'已下发','tag tag-info','检查告知已下发机构')">下发</button></td></tr>
|
||||
<tr data-number="JC-2026-018" data-institution="重庆恒安安全评价有限公司" data-type="项目过程检查" data-source="风险预警" data-warning="W-PROJ-2026-009" data-leader="刘敏" data-date="2026-07-22" data-confirm="已确认" data-feedback="已提交" data-status="已反馈"><td>JC-2026-018</td><td>重庆恒安安全评价有限公司</td><td>项目过程检查</td><td>2026-07-22 09:30</td><td>风险预警<br><span class="source-pill">W-PROJ-2026-009</span></td><td>刘敏</td><td><span class="tag tag-success">已确认</span></td><td>已提交</td><td><span class="tag tag-info">已反馈</span></td><td><button class="btn btn-primary btn-sm" onclick="openRegModal('inspectionDetail','JC-2026-018')">查看</button> <button class="btn btn-ghost btn-sm" onclick="openRegModal('inspectionResult','JC-2026-018')">登记结果</button></td></tr>
|
||||
<tr data-number="JC-2026-019" data-institution="重庆渝安风险评估中心" data-type="资质保持检查" data-source="风险预警" data-warning="W-QUAL-2026-012" data-leader="陈涛" data-date="2026-07-25" data-confirm="未确认" data-feedback="未提交" data-status="已下发"><td>JC-2026-019</td><td>重庆渝安风险评估中心</td><td>资质保持检查</td><td>2026-07-25 14:00</td><td>风险预警<br><span class="source-pill">W-QUAL-2026-012</span></td><td>陈涛</td><td><span class="tag tag-warning">未确认</span></td><td>未提交</td><td><span class="tag tag-info">已下发</span></td><td><button class="btn btn-primary btn-sm" onclick="openRegModal('inspectionDetail','JC-2026-019')">查看</button> <button class="btn btn-ghost btn-sm" onclick="showRegToast('已再次提醒机构确认')">提醒</button></td></tr>
|
||||
<tr data-number="JC-2026-012" data-institution="北京中安评价中心重庆分公司" data-type="资质保持检查" data-source="专项安排" data-warning="" data-leader="周强" data-date="2026-06-18" data-confirm="已确认" data-feedback="已提交" data-status="已完成"><td>JC-2026-012</td><td>北京中安评价中心重庆分公司</td><td>资质保持检查</td><td>2026-06-18 09:00</td><td>专项安排</td><td>周强</td><td><span class="tag tag-success">已确认</span></td><td>已提交</td><td><span class="tag tag-success">已完成</span></td><td><button class="btn btn-primary btn-sm" onclick="openRegModal('inspectionDetail','JC-2026-012')">查看</button> <button class="btn btn-ghost btn-sm" onclick="showRegToast('检查记录已加入下载任务')">下载记录</button></td></tr>
|
||||
</tbody></table></div>
|
||||
</div>
|
||||
<div class="module-page" id="mod-training-course">
|
||||
<div class="training-list-head"><span class="training-back" onclick="switchModule('dashboard')">← 返回</span><h2>课程列表</h2></div>
|
||||
<div class="search-form"><div class="row"><div class="field"><label>课程名称</label><input placeholder="请输入名称"></div><div class="field"><label>培训类型</label><select><option value="">请选择</option><option>法律法规</option><option>专业能力</option><option>事故警示</option><option>过程控制</option></select></div><div class="field"><label>课程状态</label><select><option value="">请选择课程状态</option><option>启用</option><option>禁用</option></select></div><div class="actions"><button class="btn btn-primary" onclick="filterNearestTable(this)">🔍 搜索</button><button class="btn" style="background:#10b981;color:#fff" onclick="resetNearestFilters(this)">↻ 重置</button></div></div></div>
|
||||
<div class="data-table training-table"><table><thead><tr><th><input type="checkbox" onclick="toggleRegChecks(this,'training-course-table')"></th><th>序号</th><th>课程名称</th><th>课程描述</th><th>课程状态</th><th>总课时</th><th>上传单位</th><th>操作</th></tr></thead><tbody id="training-course-table">
|
||||
<tr><td><input type="checkbox"></td><td>1</td><td class="course-name">安全生产举报和奖励办法专题培训</td><td class="course-desc">安全生产举报奖励制度、受理范围及内部报告奖励工作要求。</td><td><span class="tag tag-success">● 启用</span></td><td>0.7</td><td>重庆市应急管理局</td><td><div class="compact-actions"><button class="btn btn-primary btn-sm" onclick="toggleRowStatus(this,'● 禁用','tag tag-warning','课程已禁用')">禁用</button><button class="btn btn-primary btn-sm" onclick="openRegModal('trainingCourseEdit','安全生产举报和奖励办法专题培训')">编辑</button><button class="btn btn-danger btn-sm" onclick="deleteRegRow(this,'课程已删除')">删除</button></div></td></tr>
|
||||
<tr><td><input type="checkbox"></td><td>2</td><td class="course-name">2026年春节前安全培训</td><td class="course-desc">节前安全培训和工作重点提醒。</td><td><span class="tag tag-success">● 启用</span></td><td>0.2</td><td>重庆市应急管理局</td><td><div class="compact-actions"><button class="btn btn-primary btn-sm" onclick="toggleRowStatus(this,'● 禁用','tag tag-warning','课程已禁用')">禁用</button><button class="btn btn-primary btn-sm" onclick="openRegModal('trainingCourseEdit','2026年春节前安全培训')">编辑</button><button class="btn btn-danger btn-sm" onclick="deleteRegRow(this,'课程已删除')">删除</button></div></td></tr>
|
||||
<tr><td><input type="checkbox"></td><td>3</td><td class="course-name">典型事故案例分析</td><td class="course-desc">化工、矿山和工贸行业典型事故案例警示。</td><td><span class="tag tag-success">● 启用</span></td><td>0.3</td><td>重庆市应急管理局</td><td><div class="compact-actions"><button class="btn btn-primary btn-sm" onclick="toggleRowStatus(this,'● 禁用','tag tag-warning','课程已禁用')">禁用</button><button class="btn btn-primary btn-sm" onclick="openRegModal('training
|
||||
|
|
@ -4,17 +4,21 @@
|
|||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> 已下发: 监管 issue
|
||||
[*] --> 待下发: 监管 save
|
||||
待下发 --> 已下发: 监管 issue(id)
|
||||
[*] --> 已下发: 监管 issue(直接新建下发)
|
||||
已下发 --> 已确认: 机构 confirm
|
||||
已确认 --> 已反馈: 机构 feedback
|
||||
已确认 --> 已办结: 监管 close(至少已确认)
|
||||
已反馈 --> 已办结: 监管 close
|
||||
已下发 --> [*]: 不可直接办结
|
||||
待下发 --> [*]: 不可确认/办结
|
||||
```
|
||||
|
||||
| 动作 | 前置 status | 结果 status | 关键字段 |
|
||||
|------|-------------|-------------|----------|
|
||||
| 监管下发 `issue` | — | 1 已下发 | `notice_no`、`send_time` |
|
||||
| 监管暂存 `save` | — / 0 | 0 待下发 | `notice_no`(新建时生成) |
|
||||
| 监管下发 `issue` | — 或 0 | 1 已下发 | `notice_no`、`send_time`;推送机构消息 |
|
||||
| 机构确认 `confirm` | 1 | 2 已确认 | `confirm_flag=1`、`confirm_time` |
|
||||
| 机构反馈 `feedback` | 2 | 3 已反馈 | 必填材料 `file_url` 已上传 |
|
||||
| 监管办结 `close` | 2 或 3 | 4 已办结 | `result_*`、`result_time` |
|
||||
|
|
|
|||
|
|
@ -5,9 +5,12 @@ import io.swagger.annotations.ApiOperation;
|
|||
import io.swagger.annotations.ApiParam;
|
||||
import org.qinan.safetyeval.client.api.institution.InstitutionEvalReportApi;
|
||||
import org.qinan.safetyeval.client.co.report.EvalReportLibraryCO;
|
||||
import org.qinan.safetyeval.client.co.report.InstitutionEvalReportSummaryCO;
|
||||
import org.qinan.safetyeval.client.dto.PageResponse;
|
||||
import org.qinan.safetyeval.client.dto.SingleResponse;
|
||||
import org.qinan.safetyeval.client.dto.institution.InstitutionEvalReportAddCmd;
|
||||
import org.qinan.safetyeval.client.dto.institution.InstitutionEvalReportPageQuery;
|
||||
import org.qinan.safetyeval.client.dto.institution.InstitutionEvalReportSubmitCmd;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
|
|
@ -21,15 +24,33 @@ public class InstitutionEvalReportController {
|
|||
@Resource
|
||||
private InstitutionEvalReportApi institutionEvalReportApi;
|
||||
|
||||
@ApiOperation("报告库页顶栏汇总")
|
||||
@GetMapping("/summary")
|
||||
public SingleResponse<InstitutionEvalReportSummaryCO> summary() {
|
||||
return institutionEvalReportApi.summary();
|
||||
}
|
||||
|
||||
@ApiOperation("分页查询本机构报告")
|
||||
@GetMapping("/page")
|
||||
public PageResponse<EvalReportLibraryCO> page(@Validated InstitutionEvalReportPageQuery query) {
|
||||
return institutionEvalReportApi.page(query);
|
||||
}
|
||||
|
||||
@ApiOperation("查询报告详情")
|
||||
@ApiOperation("查询报告详情(含 fileUrl,前端据此下载)")
|
||||
@GetMapping("/get")
|
||||
public SingleResponse<EvalReportLibraryCO> get(@ApiParam("主键ID") @RequestParam String id) {
|
||||
return institutionEvalReportApi.get(Long.parseLong(id));
|
||||
}
|
||||
|
||||
@ApiOperation("上传历史报告(对齐原型「上传历史报告」)")
|
||||
@PostMapping("/add")
|
||||
public SingleResponse<EvalReportLibraryCO> add(@Validated @RequestBody InstitutionEvalReportAddCmd cmd) {
|
||||
return institutionEvalReportApi.add(cmd);
|
||||
}
|
||||
|
||||
@ApiOperation("报送监管(未报送 → 已报送)")
|
||||
@PostMapping("/submit")
|
||||
public SingleResponse<EvalReportLibraryCO> submit(@Validated @RequestBody InstitutionEvalReportSubmitCmd cmd) {
|
||||
return institutionEvalReportApi.submit(cmd);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,10 +9,18 @@ import org.qinan.safetyeval.client.co.institution.InstitutionInspNoticeCO;
|
|||
import org.qinan.safetyeval.client.dto.PageResponse;
|
||||
import org.qinan.safetyeval.client.dto.SingleResponse;
|
||||
import org.qinan.safetyeval.client.dto.institution.*;
|
||||
import org.qinan.safetyeval.app.executor.support.InstitutionInspNoticeFileSupport;
|
||||
import org.qinan.safetyeval.domain.exception.BizException;
|
||||
import org.qinan.safetyeval.infrastructure.support.InspNoticeIdSupport;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.net.URLEncoder;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.List;
|
||||
|
||||
@Api(tags = "机构端-监督检查告知")
|
||||
|
|
@ -20,9 +28,14 @@ import java.util.List;
|
|||
@RequestMapping("/safetyEval/institution/insp-notice")
|
||||
public class InstitutionInspNoticeController {
|
||||
|
||||
private static final DateTimeFormatter FILE_TS = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
|
||||
|
||||
@Resource
|
||||
private InstitutionInspNoticeApi institutionInspNoticeApi;
|
||||
|
||||
@Resource
|
||||
private InstitutionInspNoticeFileSupport institutionInspNoticeFileSupport;
|
||||
|
||||
@ApiOperation("分页查询本机构告知")
|
||||
@GetMapping("/page")
|
||||
public PageResponse<InstitutionInspNoticeCO> page(@Validated InstitutionInspNoticePageQuery query) {
|
||||
|
|
@ -32,7 +45,7 @@ public class InstitutionInspNoticeController {
|
|||
@ApiOperation("查询告知详情")
|
||||
@GetMapping("/get")
|
||||
public SingleResponse<InstitutionInspNoticeCO> get(@ApiParam("主键ID") @RequestParam String id) {
|
||||
return institutionInspNoticeApi.get(Long.parseLong(id));
|
||||
return institutionInspNoticeApi.get(InspNoticeIdSupport.parseNoticeId(id));
|
||||
}
|
||||
|
||||
@ApiOperation("确认告知")
|
||||
|
|
@ -56,7 +69,34 @@ public class InstitutionInspNoticeController {
|
|||
|
||||
@ApiOperation("材料列表")
|
||||
@GetMapping("/materials")
|
||||
public SingleResponse<List<InspNoticeMaterialCO>> materials(@ApiParam("告知ID") @RequestParam Long noticeId) {
|
||||
return institutionInspNoticeApi.materials(noticeId);
|
||||
public SingleResponse<List<InspNoticeMaterialCO>> materials(@ApiParam("告知ID") @RequestParam String noticeId) {
|
||||
return institutionInspNoticeApi.materials(InspNoticeIdSupport.parseNoticeId(noticeId));
|
||||
}
|
||||
|
||||
@ApiOperation("导出消息清单(CSV)")
|
||||
@PostMapping("/export-messages")
|
||||
public void exportMessages(@Validated @RequestBody InstitutionInspNoticeExportCmd cmd,
|
||||
HttpServletResponse response) throws IOException {
|
||||
String fileName = "监管消息清单_" + FILE_TS.format(LocalDateTime.now()) + ".csv";
|
||||
response.setContentType("text/csv;charset=UTF-8");
|
||||
response.setHeader("Content-Disposition",
|
||||
"attachment; filename=\"" + URLEncoder.encode(fileName, "UTF-8").replace("+", "%20") + "\"");
|
||||
try {
|
||||
institutionInspNoticeFileSupport.writeMessageCsv(cmd, response.getOutputStream());
|
||||
response.flushBuffer();
|
||||
} catch (BizException ex) {
|
||||
response.reset();
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
response.setStatus(HttpServletResponse.SC_OK);
|
||||
response.getWriter().write("{\"success\":false,\"code\":\"" + ex.getCode()
|
||||
+ "\",\"errMessage\":\"" + escapeJson(ex.getMessage()) + "\"}");
|
||||
}
|
||||
}
|
||||
|
||||
private String escapeJson(String message) {
|
||||
if (message == null) {
|
||||
return "";
|
||||
}
|
||||
return message.replace("\\", "\\\\").replace("\"", "\\\"");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,40 +3,108 @@ package org.qinan.safetyeval.adapter.web.regulator;
|
|||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import org.qinan.safetyeval.app.executor.support.RegulatorEvalReportFileSupport;
|
||||
import org.qinan.safetyeval.client.api.regulator.RegulatorEvalReportApi;
|
||||
import org.qinan.safetyeval.client.co.report.EvalReportLibraryCO;
|
||||
import org.qinan.safetyeval.client.co.report.RegulatorEvalReportSummaryCO;
|
||||
import org.qinan.safetyeval.client.dto.PageResponse;
|
||||
import org.qinan.safetyeval.client.dto.SingleResponse;
|
||||
import org.qinan.safetyeval.client.dto.regulator.RegulatorEvalReportAddCmd;
|
||||
import org.qinan.safetyeval.client.dto.regulator.RegulatorEvalReportBatchDownloadCmd;
|
||||
import org.qinan.safetyeval.client.dto.regulator.RegulatorEvalReportExportCmd;
|
||||
import org.qinan.safetyeval.client.dto.regulator.RegulatorEvalReportPageQuery;
|
||||
import org.qinan.safetyeval.domain.exception.BizException;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.net.URLEncoder;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
@Api(tags = "监管端-安评报告库")
|
||||
@RestController
|
||||
@RequestMapping("/safetyEval/regulator/eval-report")
|
||||
public class RegulatorEvalReportController {
|
||||
|
||||
private static final DateTimeFormatter FILE_TS = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
|
||||
|
||||
@Resource
|
||||
private RegulatorEvalReportApi regulatorEvalReportApi;
|
||||
|
||||
@ApiOperation("分页查询报告")
|
||||
@Resource
|
||||
private RegulatorEvalReportFileSupport regulatorEvalReportFileSupport;
|
||||
|
||||
@ApiOperation("报告数据库页顶栏汇总(近三年/本年度/已报送总数)")
|
||||
@GetMapping("/summary")
|
||||
public SingleResponse<RegulatorEvalReportSummaryCO> summary() {
|
||||
return regulatorEvalReportApi.summary();
|
||||
}
|
||||
|
||||
@ApiOperation("分页查询已报送报告(跨机构;默认 submitFlag=1)")
|
||||
@GetMapping("/page")
|
||||
public PageResponse<EvalReportLibraryCO> page(@Validated RegulatorEvalReportPageQuery query) {
|
||||
return regulatorEvalReportApi.page(query);
|
||||
}
|
||||
|
||||
@ApiOperation("查询报告详情")
|
||||
@ApiOperation("查询报告详情(含 fileUrl;单份下载前端可用 fileUrl)")
|
||||
@GetMapping("/get")
|
||||
public SingleResponse<EvalReportLibraryCO> get(@ApiParam("主键ID") @RequestParam String id) {
|
||||
return regulatorEvalReportApi.get(Long.parseLong(id));
|
||||
}
|
||||
|
||||
@ApiOperation("补录历史报告")
|
||||
@ApiOperation("补录历史报告(字段与机构端上传对齐,强制已报送)")
|
||||
@PostMapping("/add")
|
||||
public SingleResponse<EvalReportLibraryCO> add(@Validated @RequestBody RegulatorEvalReportAddCmd cmd) {
|
||||
return regulatorEvalReportApi.add(cmd);
|
||||
}
|
||||
|
||||
@ApiOperation("批量下载报告文件(ZIP;最多50份)")
|
||||
@PostMapping("/batch-download")
|
||||
public void batchDownload(@Validated @RequestBody RegulatorEvalReportBatchDownloadCmd cmd,
|
||||
HttpServletResponse response) throws IOException {
|
||||
String fileName = "安评报告批量下载_" + FILE_TS.format(LocalDateTime.now()) + ".zip";
|
||||
response.setContentType("application/zip");
|
||||
response.setHeader("Content-Disposition",
|
||||
"attachment; filename=\"" + URLEncoder.encode(fileName, "UTF-8").replace("+", "%20") + "\"");
|
||||
try {
|
||||
regulatorEvalReportFileSupport.writeBatchZip(cmd.getIds(), response.getOutputStream());
|
||||
response.flushBuffer();
|
||||
} catch (BizException ex) {
|
||||
response.reset();
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
response.setStatus(HttpServletResponse.SC_OK);
|
||||
response.getWriter().write("{\"success\":false,\"code\":\"" + ex.getCode()
|
||||
+ "\",\"errMessage\":\"" + escapeJson(ex.getMessage()) + "\"}");
|
||||
}
|
||||
}
|
||||
|
||||
@ApiOperation("导出报告目录(CSV,Excel可打开;勾选优先,否则按筛选,最多5000行)")
|
||||
@PostMapping("/export-catalog")
|
||||
public void exportCatalog(@Validated @RequestBody RegulatorEvalReportExportCmd cmd,
|
||||
HttpServletResponse response) throws IOException {
|
||||
String fileName = "安评报告数据库目录_" + FILE_TS.format(LocalDateTime.now()) + ".csv";
|
||||
response.setContentType("text/csv;charset=UTF-8");
|
||||
response.setHeader("Content-Disposition",
|
||||
"attachment; filename=\"" + URLEncoder.encode(fileName, "UTF-8").replace("+", "%20") + "\"");
|
||||
try {
|
||||
regulatorEvalReportFileSupport.writeCatalogCsv(cmd, response.getOutputStream());
|
||||
response.flushBuffer();
|
||||
} catch (BizException ex) {
|
||||
response.reset();
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
response.setStatus(HttpServletResponse.SC_OK);
|
||||
response.getWriter().write("{\"success\":false,\"code\":\"" + ex.getCode()
|
||||
+ "\",\"errMessage\":\"" + escapeJson(ex.getMessage()) + "\"}");
|
||||
}
|
||||
}
|
||||
|
||||
private String escapeJson(String message) {
|
||||
if (message == null) {
|
||||
return "";
|
||||
}
|
||||
return message.replace("\\", "\\\\").replace("\"", "\\\"");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,16 +3,24 @@ package org.qinan.safetyeval.adapter.web.regulator;
|
|||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import org.qinan.safetyeval.app.executor.support.RegulatorInspNoticeFileSupport;
|
||||
import org.qinan.safetyeval.client.api.regulator.RegulatorInspNoticeApi;
|
||||
import org.qinan.safetyeval.client.co.insp.InspNoticeMaterialCO;
|
||||
import org.qinan.safetyeval.client.co.regulator.RegulatorInspNoticeCO;
|
||||
import org.qinan.safetyeval.client.dto.PageResponse;
|
||||
import org.qinan.safetyeval.client.dto.SingleResponse;
|
||||
import org.qinan.safetyeval.client.dto.regulator.*;
|
||||
import org.qinan.safetyeval.domain.exception.BizException;
|
||||
import org.qinan.safetyeval.infrastructure.support.InspNoticeIdSupport;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.net.URLEncoder;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.List;
|
||||
|
||||
@Api(tags = "监管端-监督检查告知")
|
||||
|
|
@ -20,10 +28,21 @@ import java.util.List;
|
|||
@RequestMapping("/safetyEval/regulator/insp-notice")
|
||||
public class RegulatorInspNoticeController {
|
||||
|
||||
private static final DateTimeFormatter FILE_TS = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
|
||||
|
||||
@Resource
|
||||
private RegulatorInspNoticeApi regulatorInspNoticeApi;
|
||||
|
||||
@ApiOperation("新建并下发告知")
|
||||
@Resource
|
||||
private RegulatorInspNoticeFileSupport regulatorInspNoticeFileSupport;
|
||||
|
||||
@ApiOperation("暂存/编辑待下发告知")
|
||||
@PostMapping("/save")
|
||||
public SingleResponse<RegulatorInspNoticeCO> save(@Validated @RequestBody RegulatorInspNoticeSaveCmd cmd) {
|
||||
return regulatorInspNoticeApi.save(cmd);
|
||||
}
|
||||
|
||||
@ApiOperation("新建并下发告知;或对草稿下发(传 id)")
|
||||
@PostMapping("/issue")
|
||||
public SingleResponse<RegulatorInspNoticeCO> issue(@Validated @RequestBody RegulatorInspNoticeIssueCmd cmd) {
|
||||
return regulatorInspNoticeApi.issue(cmd);
|
||||
|
|
@ -38,7 +57,7 @@ public class RegulatorInspNoticeController {
|
|||
@ApiOperation("查询告知详情")
|
||||
@GetMapping("/get")
|
||||
public SingleResponse<RegulatorInspNoticeCO> get(@ApiParam("主键ID") @RequestParam String id) {
|
||||
return regulatorInspNoticeApi.get(Long.parseLong(id));
|
||||
return regulatorInspNoticeApi.get(InspNoticeIdSupport.parseNoticeId(id));
|
||||
}
|
||||
|
||||
@ApiOperation("登记结果并办结")
|
||||
|
|
@ -47,10 +66,16 @@ public class RegulatorInspNoticeController {
|
|||
return regulatorInspNoticeApi.close(cmd);
|
||||
}
|
||||
|
||||
@ApiOperation("保存监管备注")
|
||||
@PostMapping("/remark")
|
||||
public SingleResponse<RegulatorInspNoticeCO> remark(@Validated @RequestBody RegulatorInspNoticeRemarkCmd cmd) {
|
||||
return regulatorInspNoticeApi.remark(cmd);
|
||||
}
|
||||
|
||||
@ApiOperation("材料只读列表")
|
||||
@GetMapping("/materials")
|
||||
public SingleResponse<List<InspNoticeMaterialCO>> materials(@ApiParam("告知ID") @RequestParam Long noticeId) {
|
||||
return regulatorInspNoticeApi.materials(noticeId);
|
||||
public SingleResponse<List<InspNoticeMaterialCO>> materials(@ApiParam("告知ID") @RequestParam String noticeId) {
|
||||
return regulatorInspNoticeApi.materials(InspNoticeIdSupport.parseNoticeId(noticeId));
|
||||
}
|
||||
|
||||
@ApiOperation("催办(重发机构消息)")
|
||||
|
|
@ -58,4 +83,52 @@ public class RegulatorInspNoticeController {
|
|||
public SingleResponse<Void> urge(@Validated @RequestBody RegulatorInspNoticeUrgeCmd cmd) {
|
||||
return regulatorInspNoticeApi.urge(cmd);
|
||||
}
|
||||
|
||||
@ApiOperation("导出台账(CSV,Excel可打开;勾选优先,否则按筛选,最多5000行)")
|
||||
@PostMapping("/export-ledger")
|
||||
public void exportLedger(@Validated @RequestBody RegulatorInspNoticeExportCmd cmd,
|
||||
HttpServletResponse response) throws IOException {
|
||||
String fileName = "监督检查告知台账_" + FILE_TS.format(LocalDateTime.now()) + ".csv";
|
||||
response.setContentType("text/csv;charset=UTF-8");
|
||||
response.setHeader("Content-Disposition",
|
||||
"attachment; filename=\"" + URLEncoder.encode(fileName, "UTF-8").replace("+", "%20") + "\"");
|
||||
try {
|
||||
regulatorInspNoticeFileSupport.writeLedgerCsv(cmd, response.getOutputStream());
|
||||
response.flushBuffer();
|
||||
} catch (BizException ex) {
|
||||
response.reset();
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
response.setStatus(HttpServletResponse.SC_OK);
|
||||
response.getWriter().write("{\"success\":false,\"code\":\"" + ex.getCode()
|
||||
+ "\",\"errMessage\":\"" + escapeJson(ex.getMessage()) + "\"}");
|
||||
}
|
||||
}
|
||||
|
||||
@ApiOperation("下载检查记录(CSV)")
|
||||
@GetMapping("/download-record")
|
||||
public void downloadRecord(@ApiParam("告知ID") @RequestParam String id,
|
||||
HttpServletResponse response) throws IOException {
|
||||
Long noticeId = InspNoticeIdSupport.parseNoticeId(id);
|
||||
String fileName = "监督检查记录_" + id + "_" + FILE_TS.format(LocalDateTime.now()) + ".csv";
|
||||
response.setContentType("text/csv;charset=UTF-8");
|
||||
response.setHeader("Content-Disposition",
|
||||
"attachment; filename=\"" + URLEncoder.encode(fileName, "UTF-8").replace("+", "%20") + "\"");
|
||||
try {
|
||||
regulatorInspNoticeFileSupport.writeRecordCsv(noticeId, response.getOutputStream());
|
||||
response.flushBuffer();
|
||||
} catch (BizException ex) {
|
||||
response.reset();
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
response.setStatus(HttpServletResponse.SC_OK);
|
||||
response.getWriter().write("{\"success\":false,\"code\":\"" + ex.getCode()
|
||||
+ "\",\"errMessage\":\"" + escapeJson(ex.getMessage()) + "\"}");
|
||||
}
|
||||
}
|
||||
|
||||
private String escapeJson(String message) {
|
||||
if (message == null) {
|
||||
return "";
|
||||
}
|
||||
return message.replace("\\", "\\\\").replace("\"", "\\\"");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -438,6 +438,7 @@ public class EvalProcessControlExecutor implements EvalProcessControlApi {
|
|||
report.setEvalTypeName(evalType != null ? evalType.getValue() : null);
|
||||
report.setPublicFlag(2);
|
||||
report.setCompleteFlag(1);
|
||||
report.setSubmitFlag(1);
|
||||
report.setReportStatusCode(1);
|
||||
report.setReportStatusName("已入库");
|
||||
report.setArchiveTime(LocalDateTime.now());
|
||||
|
|
|
|||
|
|
@ -3,9 +3,12 @@ package org.qinan.safetyeval.app.executor.institution;
|
|||
import org.qinan.safetyeval.app.executor.support.ReportProfileCoConverter;
|
||||
import org.qinan.safetyeval.client.api.institution.InstitutionEvalReportApi;
|
||||
import org.qinan.safetyeval.client.co.report.EvalReportLibraryCO;
|
||||
import org.qinan.safetyeval.client.co.report.InstitutionEvalReportSummaryCO;
|
||||
import org.qinan.safetyeval.client.dto.PageResponse;
|
||||
import org.qinan.safetyeval.client.dto.SingleResponse;
|
||||
import org.qinan.safetyeval.client.dto.institution.InstitutionEvalReportAddCmd;
|
||||
import org.qinan.safetyeval.client.dto.institution.InstitutionEvalReportPageQuery;
|
||||
import org.qinan.safetyeval.client.dto.institution.InstitutionEvalReportSubmitCmd;
|
||||
import org.qinan.safetyeval.domain.entity.EvalReportEntity;
|
||||
import org.qinan.safetyeval.domain.exception.ErrorCode;
|
||||
import org.qinan.safetyeval.domain.query.EvalReportQuery;
|
||||
|
|
@ -15,7 +18,9 @@ import org.qinan.safetyeval.infrastructure.support.InstitutionOrgSupport;
|
|||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
|
|
@ -37,7 +42,9 @@ public class InstitutionEvalReportExecutor implements InstitutionEvalReportApi {
|
|||
domainQuery.setOrgId(institutionOrgSupport.resolveCurrentOrgId());
|
||||
domainQuery.setReportYear(query.getReportYear());
|
||||
domainQuery.setEvalTypeCode(query.getEvalTypeCode());
|
||||
domainQuery.setReportStatusCode(query.getReportStatusCode());
|
||||
domainQuery.setIndustryCode(query.getIndustryCode());
|
||||
domainQuery.setKeyword(query.getKeyword());
|
||||
applyDisplayStatus(domainQuery, query.getDisplayStatus(), query.getReportStatusCode());
|
||||
PageResult<EvalReportEntity> pageResult = evalReportDomainService.page(domainQuery);
|
||||
return PageResponse.of(
|
||||
pageResult.getRecords().stream().map(ReportProfileCoConverter::toReportCO).collect(Collectors.toList()),
|
||||
|
|
@ -50,4 +57,145 @@ public class InstitutionEvalReportExecutor implements InstitutionEvalReportApi {
|
|||
institutionOrgSupport.assertOrgAccess(entity.getOrgId(), ErrorCode.EVAL_REPORT_ORG_MISMATCH);
|
||||
return SingleResponse.success(ReportProfileCoConverter.toReportCO(entity));
|
||||
}
|
||||
|
||||
@Override
|
||||
public SingleResponse<InstitutionEvalReportSummaryCO> summary() {
|
||||
Long orgId = institutionOrgSupport.resolveCurrentOrgId();
|
||||
InstitutionEvalReportSummaryCO co = new InstitutionEvalReportSummaryCO();
|
||||
co.setTotalCount(countBase(orgId, null, null, null, null));
|
||||
int yearFrom = LocalDate.now().getYear() - 2;
|
||||
co.setRecentThreeYearCount(countBase(orgId, null, null, null, yearFrom));
|
||||
co.setSubmittedCount(countBase(orgId, 1, null, null, null));
|
||||
co.setIncompleteCount(countByCompleteFlag(orgId, 2));
|
||||
co.setSpotcheckingCount(countBase(orgId, null, EvalReportDomainService.STATUS_SPOTCHECKING, null, null));
|
||||
return SingleResponse.success(co);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SingleResponse<EvalReportLibraryCO> add(InstitutionEvalReportAddCmd cmd) {
|
||||
Long orgId = institutionOrgSupport.resolveCurrentOrgId();
|
||||
EvalReportEntity entity = new EvalReportEntity();
|
||||
entity.setOrgId(orgId);
|
||||
entity.setReportNo(cmd.getReportNo().trim());
|
||||
entity.setReportName(cmd.getReportName().trim());
|
||||
entity.setReportYear(cmd.getReportYear() != null ? cmd.getReportYear() : LocalDate.now().getYear());
|
||||
entity.setEvalTypeCode(cmd.getEvalTypeCode());
|
||||
entity.setEvalTypeName(resolveEvalTypeName(cmd.getEvalTypeCode(), cmd.getEvalTypeName()));
|
||||
entity.setIndustryCode(cmd.getIndustryCode());
|
||||
entity.setIndustryName(cmd.getIndustryName());
|
||||
entity.setEvaluatedUnitName(cmd.getEvaluatedUnitName().trim());
|
||||
entity.setCustomerId(cmd.getCustomerId());
|
||||
entity.setIssueDate(cmd.getIssueDate());
|
||||
entity.setPageCount(cmd.getPageCount());
|
||||
entity.setFileUrl(cmd.getFileUrl());
|
||||
entity.setFileName(cmd.getFileName());
|
||||
entity.setSecretLevelCode(cmd.getSecretLevelCode());
|
||||
entity.setSecretLevelName(resolveSecretName(cmd.getSecretLevelCode(), cmd.getSecretLevelName()));
|
||||
entity.setRemarks(cmd.getRemarks());
|
||||
boolean submit = Boolean.TRUE.equals(cmd.getSubmitToRegulator());
|
||||
entity.setSubmitFlag(submit ? 1 : 2);
|
||||
EvalReportEntity result = evalReportDomainService.addForInstitution(entity);
|
||||
return SingleResponse.success(ReportProfileCoConverter.toReportCO(result));
|
||||
}
|
||||
|
||||
@Override
|
||||
public SingleResponse<EvalReportLibraryCO> submit(InstitutionEvalReportSubmitCmd cmd) {
|
||||
EvalReportEntity existing = evalReportDomainService.get(cmd.getId());
|
||||
institutionOrgSupport.assertOrgAccess(existing.getOrgId(), ErrorCode.EVAL_REPORT_ORG_MISMATCH);
|
||||
EvalReportEntity result = evalReportDomainService.submitToRegulator(cmd.getId());
|
||||
return SingleResponse.success(ReportProfileCoConverter.toReportCO(result));
|
||||
}
|
||||
|
||||
private void applyDisplayStatus(EvalReportQuery query, String displayStatus, Integer reportStatusCode) {
|
||||
if (StringUtils.hasText(displayStatus)) {
|
||||
String status = displayStatus.trim().toUpperCase();
|
||||
if ("UN_SUBMITTED".equals(status) || "未报送".equals(displayStatus.trim())) {
|
||||
query.setSubmitFlag(2);
|
||||
return;
|
||||
}
|
||||
if ("SUBMITTED".equals(status) || "已报送".equals(displayStatus.trim())) {
|
||||
query.setSubmitFlag(1);
|
||||
query.setReportStatusCode(EvalReportDomainService.STATUS_ARCHIVED);
|
||||
return;
|
||||
}
|
||||
if ("SPOTCHECKING".equals(status) || "抽查中".equals(displayStatus.trim())) {
|
||||
query.setReportStatusCode(EvalReportDomainService.STATUS_SPOTCHECKING);
|
||||
return;
|
||||
}
|
||||
if ("RECTIFYING".equals(status) || "整改中".equals(displayStatus.trim())) {
|
||||
query.setReportStatusCode(EvalReportDomainService.STATUS_RECTIFY);
|
||||
return;
|
||||
}
|
||||
if ("REVIEWED".equals(status) || "已复核".equals(displayStatus.trim())) {
|
||||
query.setReportStatusCode(EvalReportDomainService.STATUS_REVIEWED);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (reportStatusCode != null) {
|
||||
query.setReportStatusCode(reportStatusCode);
|
||||
}
|
||||
}
|
||||
|
||||
private EvalReportQuery baseQuery(Long orgId) {
|
||||
EvalReportQuery q = new EvalReportQuery();
|
||||
q.setOrgId(orgId);
|
||||
q.setPageNum(1L);
|
||||
q.setPageSize(1L);
|
||||
return q;
|
||||
}
|
||||
|
||||
private long countBase(Long orgId, Integer submitFlag, Integer statusCode, String industryCode, Integer yearFrom) {
|
||||
EvalReportQuery q = baseQuery(orgId);
|
||||
q.setSubmitFlag(submitFlag);
|
||||
q.setReportStatusCode(statusCode);
|
||||
q.setIndustryCode(industryCode);
|
||||
q.setRecentYearFrom(yearFrom);
|
||||
return evalReportDomainService.count(q);
|
||||
}
|
||||
|
||||
private long countByCompleteFlag(Long orgId, int completeFlag) {
|
||||
EvalReportQuery q = baseQuery(orgId);
|
||||
q.setCompleteFlag(completeFlag);
|
||||
return evalReportDomainService.count(q);
|
||||
}
|
||||
|
||||
private String resolveEvalTypeName(String code, String name) {
|
||||
if (StringUtils.hasText(name)) {
|
||||
return name.trim();
|
||||
}
|
||||
if (!StringUtils.hasText(code)) {
|
||||
return null;
|
||||
}
|
||||
switch (code.trim().toUpperCase()) {
|
||||
case "PRE":
|
||||
return "安全预评价";
|
||||
case "ACCEPT":
|
||||
return "安全验收评价";
|
||||
case "STATUS":
|
||||
return "安全现状评价";
|
||||
default:
|
||||
return code;
|
||||
}
|
||||
}
|
||||
|
||||
private String resolveSecretName(String code, String name) {
|
||||
if (StringUtils.hasText(name)) {
|
||||
return name.trim();
|
||||
}
|
||||
if (!StringUtils.hasText(code)) {
|
||||
return null;
|
||||
}
|
||||
switch (code.trim().toUpperCase()) {
|
||||
case "NORMAL":
|
||||
return "普通";
|
||||
case "TRADE_SECRET":
|
||||
return "含商业秘密";
|
||||
case "PRIVACY":
|
||||
return "涉个人隐私";
|
||||
case "CLASSIFIED":
|
||||
return "涉密资料";
|
||||
default:
|
||||
return code;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import org.qinan.safetyeval.domain.query.PageResult;
|
|||
import org.qinan.safetyeval.domain.service.InspNoticeDomainService;
|
||||
import org.qinan.safetyeval.domain.service.InspNoticeMaterialDomainService;
|
||||
import org.qinan.safetyeval.infrastructure.adapter.auth.AuthUserContextAdapter;
|
||||
import org.qinan.safetyeval.infrastructure.support.InspNoticeIdSupport;
|
||||
import org.qinan.safetyeval.infrastructure.support.InspNoticeMessageHelper;
|
||||
import org.qinan.safetyeval.infrastructure.support.InstitutionOrgSupport;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
|
@ -64,8 +65,17 @@ public class InstitutionInspNoticeExecutor implements InstitutionInspNoticeApi {
|
|||
domainQuery.setPageSize(query.getSize());
|
||||
domainQuery.setOrgId(institutionOrgSupport.resolveCurrentOrgId());
|
||||
domainQuery.setNoticeNo(query.getNoticeNo());
|
||||
domainQuery.setKeyword(query.getKeyword());
|
||||
domainQuery.setStatusCode(query.getStatusCode());
|
||||
domainQuery.setInspTypeCode(query.getInspTypeCode());
|
||||
domainQuery.setSourceTypeCode(query.getSourceTypeCode());
|
||||
domainQuery.setSourceRefNo(query.getSourceRefNo());
|
||||
domainQuery.setConfirmFlag(query.getConfirmFlag());
|
||||
domainQuery.setFeedbackFlag(query.getFeedbackFlag());
|
||||
// 机构端不展示待下发草稿
|
||||
if (query.getStatusCode() == null) {
|
||||
domainQuery.setMinStatusCode(InspNoticeDomainService.STATUS_ISSUED);
|
||||
}
|
||||
PageResult<InspNoticeEntity> pageResult = inspNoticeDomainService.page(domainQuery);
|
||||
return PageResponse.of(
|
||||
pageResult.getRecords().stream().map(this::toCO).collect(Collectors.toList()),
|
||||
|
|
@ -74,37 +84,41 @@ public class InstitutionInspNoticeExecutor implements InstitutionInspNoticeApi {
|
|||
|
||||
@Override
|
||||
public SingleResponse<InstitutionInspNoticeCO> confirm(InstitutionInspNoticeConfirmCmd cmd) {
|
||||
InspNoticeEntity existing = inspNoticeDomainService.get(cmd.getId());
|
||||
Long noticeId = InspNoticeIdSupport.parseNoticeId(cmd.getId());
|
||||
InspNoticeEntity existing = inspNoticeDomainService.get(noticeId);
|
||||
inspNoticeDomainService.assertOrgAccess(existing, institutionOrgSupport.resolveCurrentOrgId());
|
||||
InspNoticeEntity result = inspNoticeDomainService.confirm(cmd.getId());
|
||||
InspNoticeEntity result = inspNoticeDomainService.confirm(noticeId);
|
||||
return SingleResponse.success(toCO(result));
|
||||
}
|
||||
|
||||
@Override
|
||||
public SingleResponse<InstitutionInspNoticeCO> feedback(InstitutionInspNoticeFeedbackCmd cmd) {
|
||||
InspNoticeEntity existing = inspNoticeDomainService.get(cmd.getId());
|
||||
Long noticeId = InspNoticeIdSupport.parseNoticeId(cmd.getId());
|
||||
InspNoticeEntity existing = inspNoticeDomainService.get(noticeId);
|
||||
inspNoticeDomainService.assertOrgAccess(existing, institutionOrgSupport.resolveCurrentOrgId());
|
||||
Long lastMaterialId = null;
|
||||
if (!CollectionUtils.isEmpty(cmd.getMaterials())) {
|
||||
for (InstitutionInspNoticeMaterialUploadCmd item : cmd.getMaterials()) {
|
||||
InspNoticeMaterialEntity material = inspNoticeMaterialDomainService.get(item.getMaterialId());
|
||||
if (!cmd.getId().equals(material.getNoticeId())
|
||||
Long materialId = InspNoticeIdSupport.parseMaterialId(item.getMaterialId());
|
||||
InspNoticeMaterialEntity material = inspNoticeMaterialDomainService.get(materialId);
|
||||
if (!noticeId.equals(material.getNoticeId())
|
||||
|| !existing.getOrgId().equals(material.getOrgId())) {
|
||||
throw new BizException(ErrorCode.INSP_NOTICE_MATERIAL_NOT_FOUND);
|
||||
}
|
||||
inspNoticeMaterialDomainService.upload(item.getMaterialId(), item.getFileUrl());
|
||||
lastMaterialId = item.getMaterialId();
|
||||
inspNoticeMaterialDomainService.upload(materialId, item.getFileUrl());
|
||||
lastMaterialId = materialId;
|
||||
}
|
||||
}
|
||||
inspNoticeMaterialDomainService.assertRequiredMaterialsUploaded(cmd.getId());
|
||||
InspNoticeEntity result = inspNoticeDomainService.feedback(cmd.getId());
|
||||
inspNoticeMaterialDomainService.assertRequiredMaterialsUploaded(noticeId);
|
||||
InspNoticeEntity result = inspNoticeDomainService.feedback(noticeId);
|
||||
sendRegMessage(result, lastMaterialId);
|
||||
return SingleResponse.success(toCO(result));
|
||||
}
|
||||
|
||||
@Override
|
||||
public SingleResponse<InspNoticeMaterialCO> uploadMaterial(InstitutionInspNoticeMaterialUploadCmd cmd) {
|
||||
InspNoticeMaterialEntity material = inspNoticeMaterialDomainService.get(cmd.getMaterialId());
|
||||
Long materialId = InspNoticeIdSupport.parseMaterialId(cmd.getMaterialId());
|
||||
InspNoticeMaterialEntity material = inspNoticeMaterialDomainService.get(materialId);
|
||||
InspNoticeEntity notice = inspNoticeDomainService.get(material.getNoticeId());
|
||||
inspNoticeDomainService.assertOrgAccess(notice, institutionOrgSupport.resolveCurrentOrgId());
|
||||
if (!notice.getOrgId().equals(material.getOrgId())) {
|
||||
|
|
@ -116,7 +130,7 @@ public class InstitutionInspNoticeExecutor implements InstitutionInspNoticeApi {
|
|||
&& status != InspNoticeDomainService.STATUS_FEEDBACK)) {
|
||||
throw new BizException(ErrorCode.INSP_NOTICE_STATUS_INVALID);
|
||||
}
|
||||
InspNoticeMaterialEntity result = inspNoticeMaterialDomainService.upload(cmd.getMaterialId(), cmd.getFileUrl());
|
||||
InspNoticeMaterialEntity result = inspNoticeMaterialDomainService.upload(materialId, cmd.getFileUrl());
|
||||
return SingleResponse.success(toMaterialCO(result));
|
||||
}
|
||||
|
||||
|
|
@ -151,12 +165,16 @@ public class InstitutionInspNoticeExecutor implements InstitutionInspNoticeApi {
|
|||
co.setInspTypeName(entity.getInspTypeName());
|
||||
co.setSourceTypeCode(entity.getSourceTypeCode());
|
||||
co.setSourceTypeName(entity.getSourceTypeName());
|
||||
co.setSourceRefNo(entity.getSourceRefNo());
|
||||
co.setPlanInspTime(entity.getPlanInspTime());
|
||||
co.setLeaderName(entity.getLeaderName());
|
||||
co.setNoticeContent(entity.getNoticeContent());
|
||||
co.setNoticeUrls(entity.getNoticeUrls());
|
||||
co.setStatusCode(entity.getStatusCode());
|
||||
co.setStatusName(entity.getStatusName());
|
||||
co.setConfirmFlag(entity.getConfirmFlag());
|
||||
co.setFeedbackFlag(entity.getStatusCode() != null
|
||||
&& entity.getStatusCode() >= InspNoticeDomainService.STATUS_FEEDBACK ? 1 : 2);
|
||||
co.setConfirmTime(entity.getConfirmTime());
|
||||
co.setSendTime(entity.getSendTime());
|
||||
co.setResultCode(entity.getResultCode());
|
||||
|
|
@ -164,6 +182,7 @@ public class InstitutionInspNoticeExecutor implements InstitutionInspNoticeApi {
|
|||
co.setResultContent(entity.getResultContent());
|
||||
co.setResultUrls(entity.getResultUrls());
|
||||
co.setResultTime(entity.getResultTime());
|
||||
co.setRemarks(entity.getRemarks());
|
||||
return co;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,19 +3,33 @@ package org.qinan.safetyeval.app.executor.regulator;
|
|||
import org.qinan.safetyeval.app.executor.support.ReportProfileCoConverter;
|
||||
import org.qinan.safetyeval.client.api.regulator.RegulatorEvalReportApi;
|
||||
import org.qinan.safetyeval.client.co.report.EvalReportLibraryCO;
|
||||
import org.qinan.safetyeval.client.co.report.RegulatorEvalReportSummaryCO;
|
||||
import org.qinan.safetyeval.client.dto.PageResponse;
|
||||
import org.qinan.safetyeval.client.dto.SingleResponse;
|
||||
import org.qinan.safetyeval.client.dto.regulator.RegulatorEvalReportAddCmd;
|
||||
import org.qinan.safetyeval.client.dto.regulator.RegulatorEvalReportPageQuery;
|
||||
import org.qinan.safetyeval.domain.entity.EvalReportEntity;
|
||||
import org.qinan.safetyeval.domain.entity.OrgInfoEntity;
|
||||
import org.qinan.safetyeval.domain.gateway.OrgInfoGateway;
|
||||
import org.qinan.safetyeval.domain.query.EvalReportQuery;
|
||||
import org.qinan.safetyeval.domain.query.OrgInfoQuery;
|
||||
import org.qinan.safetyeval.domain.query.PageResult;
|
||||
import org.qinan.safetyeval.domain.service.EvalReportDomainService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
|
|
@ -25,6 +39,19 @@ public class RegulatorEvalReportExecutor implements RegulatorEvalReportApi {
|
|||
@Autowired(required = false)
|
||||
private EvalReportDomainService evalReportDomainService;
|
||||
|
||||
@Autowired(required = false)
|
||||
private OrgInfoGateway orgInfoGateway;
|
||||
|
||||
@Override
|
||||
public SingleResponse<RegulatorEvalReportSummaryCO> summary() {
|
||||
RegulatorEvalReportSummaryCO co = new RegulatorEvalReportSummaryCO();
|
||||
int year = LocalDate.now().getYear();
|
||||
co.setSubmittedTotalCount(countSubmitted(null, null));
|
||||
co.setRecentThreeYearCount(countSubmitted(year - 2, null));
|
||||
co.setCurrentYearCount(countSubmitted(null, year));
|
||||
return SingleResponse.success(co);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResponse<EvalReportLibraryCO> page(RegulatorEvalReportPageQuery query) {
|
||||
EvalReportQuery domainQuery = new EvalReportQuery();
|
||||
|
|
@ -33,16 +60,47 @@ public class RegulatorEvalReportExecutor implements RegulatorEvalReportApi {
|
|||
domainQuery.setOrgId(query.getOrgId());
|
||||
domainQuery.setReportYear(query.getReportYear());
|
||||
domainQuery.setEvalTypeCode(query.getEvalTypeCode());
|
||||
domainQuery.setIndustryCode(query.getIndustryCode());
|
||||
domainQuery.setReportStatusCode(query.getReportStatusCode());
|
||||
domainQuery.setKeyword(query.getKeyword());
|
||||
// 监管端报告数据库默认只看已报送
|
||||
domainQuery.setSubmitFlag(query.getSubmitFlag() != null ? query.getSubmitFlag() : 1);
|
||||
if (StringUtils.hasText(query.getArchiveTimeStart())) {
|
||||
domainQuery.setArchiveTimeFrom(LocalDate.parse(query.getArchiveTimeStart().trim()).atStartOfDay());
|
||||
}
|
||||
if (StringUtils.hasText(query.getArchiveTimeEnd())) {
|
||||
domainQuery.setArchiveTimeTo(LocalDate.parse(query.getArchiveTimeEnd().trim()).atTime(LocalTime.MAX));
|
||||
}
|
||||
if (StringUtils.hasText(query.getOrgName())) {
|
||||
List<Long> orgIds = resolveOrgIdsByName(query.getOrgName().trim());
|
||||
domainQuery.setOrgIds(orgIds);
|
||||
if (orgIds.isEmpty()) {
|
||||
return PageResponse.of(Collections.<EvalReportLibraryCO>emptyList(), 0L);
|
||||
}
|
||||
}
|
||||
PageResult<EvalReportEntity> pageResult = evalReportDomainService.page(domainQuery);
|
||||
return PageResponse.of(
|
||||
pageResult.getRecords().stream().map(ReportProfileCoConverter::toReportCO).collect(Collectors.toList()),
|
||||
pageResult.getTotal());
|
||||
Map<Long, String> orgNameMap = buildOrgNameMap(pageResult.getRecords());
|
||||
List<EvalReportLibraryCO> list = pageResult.getRecords().stream().map(entity -> {
|
||||
EvalReportLibraryCO co = ReportProfileCoConverter.toReportCO(entity);
|
||||
if (co != null && entity.getOrgId() != null) {
|
||||
co.setOrgName(orgNameMap.get(entity.getOrgId()));
|
||||
}
|
||||
return co;
|
||||
}).collect(Collectors.toList());
|
||||
return PageResponse.of(list, pageResult.getTotal());
|
||||
}
|
||||
|
||||
@Override
|
||||
public SingleResponse<EvalReportLibraryCO> get(Long id) {
|
||||
return SingleResponse.success(ReportProfileCoConverter.toReportCO(evalReportDomainService.get(id)));
|
||||
EvalReportEntity entity = evalReportDomainService.get(id);
|
||||
EvalReportLibraryCO co = ReportProfileCoConverter.toReportCO(entity);
|
||||
if (co != null && entity.getOrgId() != null && orgInfoGateway != null) {
|
||||
OrgInfoEntity org = orgInfoGateway.get(entity.getOrgId());
|
||||
if (org != null) {
|
||||
co.setOrgName(org.getUnitName());
|
||||
}
|
||||
}
|
||||
return SingleResponse.success(co);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -50,16 +108,103 @@ public class RegulatorEvalReportExecutor implements RegulatorEvalReportApi {
|
|||
EvalReportEntity entity = new EvalReportEntity();
|
||||
entity.setOrgId(cmd.getOrgId());
|
||||
entity.setProjectId(cmd.getProjectId());
|
||||
entity.setCustomerId(cmd.getCustomerId());
|
||||
entity.setEvaluatedUnitName(cmd.getEvaluatedUnitName());
|
||||
entity.setReportName(cmd.getReportName());
|
||||
entity.setReportNo(cmd.getReportNo());
|
||||
entity.setReportYear(cmd.getReportYear() != null ? cmd.getReportYear() : LocalDateTime.now().getYear());
|
||||
entity.setEvalTypeCode(cmd.getEvalTypeCode());
|
||||
entity.setEvalTypeName(cmd.getEvalTypeName());
|
||||
entity.setEvalTypeName(resolveEvalTypeName(cmd.getEvalTypeCode(), cmd.getEvalTypeName()));
|
||||
entity.setIndustryCode(cmd.getIndustryCode());
|
||||
entity.setIndustryName(cmd.getIndustryName());
|
||||
entity.setBusinessScope(cmd.getBusinessScope());
|
||||
entity.setFileUrl(cmd.getFileUrl());
|
||||
entity.setFileName(cmd.getFileName());
|
||||
entity.setIssueDate(cmd.getIssueDate());
|
||||
entity.setPageCount(cmd.getPageCount());
|
||||
entity.setSecretLevelCode(cmd.getSecretLevelCode());
|
||||
entity.setSecretLevelName(cmd.getSecretLevelName());
|
||||
entity.setRemarks(cmd.getRemarks());
|
||||
entity.setCompleteFlag(1);
|
||||
entity.setSubmitFlag(1);
|
||||
if (StringUtils.hasText(cmd.getReportNo())) {
|
||||
evalReportDomainService.assertReportNoUnique(cmd.getOrgId(), cmd.getReportNo(), null);
|
||||
}
|
||||
EvalReportEntity result = evalReportDomainService.addForRegulator(entity);
|
||||
return SingleResponse.success(ReportProfileCoConverter.toReportCO(result));
|
||||
return get(result.getId());
|
||||
}
|
||||
|
||||
private long countSubmitted(Integer yearFrom, Integer exactYear) {
|
||||
EvalReportQuery q = new EvalReportQuery();
|
||||
q.setPageNum(1L);
|
||||
q.setPageSize(1L);
|
||||
q.setSubmitFlag(1);
|
||||
if (yearFrom != null) {
|
||||
q.setRecentYearFrom(yearFrom);
|
||||
}
|
||||
if (exactYear != null) {
|
||||
q.setReportYear(exactYear);
|
||||
}
|
||||
return evalReportDomainService.count(q);
|
||||
}
|
||||
|
||||
private List<Long> resolveOrgIdsByName(String orgName) {
|
||||
if (orgInfoGateway == null || !StringUtils.hasText(orgName)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
OrgInfoQuery query = new OrgInfoQuery();
|
||||
query.setPageNum(1L);
|
||||
query.setPageSize(500L);
|
||||
query.setUnitName(orgName);
|
||||
PageResult<OrgInfoEntity> page = orgInfoGateway.page(query);
|
||||
if (page == null || page.getRecords() == null || page.getRecords().isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<Long> ids = new ArrayList<Long>();
|
||||
for (OrgInfoEntity org : page.getRecords()) {
|
||||
if (org != null && org.getId() != null) {
|
||||
ids.add(org.getId());
|
||||
}
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
|
||||
private Map<Long, String> buildOrgNameMap(List<EvalReportEntity> records) {
|
||||
Map<Long, String> map = new HashMap<Long, String>();
|
||||
if (records == null || records.isEmpty() || orgInfoGateway == null) {
|
||||
return map;
|
||||
}
|
||||
Set<Long> ids = new HashSet<Long>();
|
||||
for (EvalReportEntity entity : records) {
|
||||
if (entity != null && entity.getOrgId() != null) {
|
||||
ids.add(entity.getOrgId());
|
||||
}
|
||||
}
|
||||
for (Long id : ids) {
|
||||
OrgInfoEntity org = orgInfoGateway.get(id);
|
||||
if (org != null) {
|
||||
map.put(id, org.getUnitName());
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
private String resolveEvalTypeName(String code, String name) {
|
||||
if (StringUtils.hasText(name)) {
|
||||
return name.trim();
|
||||
}
|
||||
if (!StringUtils.hasText(code)) {
|
||||
return null;
|
||||
}
|
||||
switch (code.trim().toUpperCase()) {
|
||||
case "PRE":
|
||||
return "安全预评价";
|
||||
case "ACCEPT":
|
||||
return "安全验收评价";
|
||||
case "STATUS":
|
||||
return "安全现状评价";
|
||||
default:
|
||||
return code;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package org.qinan.safetyeval.app.executor.regulator;
|
||||
|
||||
import org.qinan.safetyeval.app.executor.support.RegulatorInspNoticeFileSupport;
|
||||
import org.qinan.safetyeval.client.api.SafetyMessageApi;
|
||||
import org.qinan.safetyeval.client.api.regulator.RegulatorInspNoticeApi;
|
||||
import org.qinan.safetyeval.client.co.insp.InspNoticeMaterialCO;
|
||||
|
|
@ -10,13 +11,16 @@ import org.qinan.safetyeval.client.dto.SingleResponse;
|
|||
import org.qinan.safetyeval.client.dto.regulator.*;
|
||||
import org.qinan.safetyeval.domain.entity.InspNoticeEntity;
|
||||
import org.qinan.safetyeval.domain.entity.InspNoticeMaterialEntity;
|
||||
import org.qinan.safetyeval.domain.entity.OrgInfoEntity;
|
||||
import org.qinan.safetyeval.domain.exception.BizException;
|
||||
import org.qinan.safetyeval.domain.exception.ErrorCode;
|
||||
import org.qinan.safetyeval.domain.gateway.OrgInfoGateway;
|
||||
import org.qinan.safetyeval.domain.query.InspNoticeQuery;
|
||||
import org.qinan.safetyeval.domain.query.PageResult;
|
||||
import org.qinan.safetyeval.domain.service.InspNoticeDomainService;
|
||||
import org.qinan.safetyeval.domain.service.InspNoticeMaterialDomainService;
|
||||
import org.qinan.safetyeval.infrastructure.adapter.auth.AuthUserContextAdapter;
|
||||
import org.qinan.safetyeval.infrastructure.support.InspNoticeIdSupport;
|
||||
import org.qinan.safetyeval.infrastructure.support.InspNoticeMessageHelper;
|
||||
import org.qinan.safetyeval.infrastructure.support.NoticeNoGenerator;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
|
@ -28,7 +32,11 @@ import org.springframework.util.StringUtils;
|
|||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
|
|
@ -50,48 +58,79 @@ public class RegulatorInspNoticeExecutor implements RegulatorInspNoticeApi {
|
|||
@Autowired(required = false)
|
||||
private InspNoticeMessageHelper inspNoticeMessageHelper;
|
||||
|
||||
@Lazy
|
||||
@Autowired(required = false)
|
||||
private RegulatorInspNoticeFileSupport regulatorInspNoticeFileSupport;
|
||||
|
||||
@Autowired(required = false)
|
||||
private OrgInfoGateway orgInfoGateway;
|
||||
|
||||
@Resource
|
||||
private SafetyMessageApi safetyMessageApi;
|
||||
|
||||
@Override
|
||||
public SingleResponse<RegulatorInspNoticeCO> issue(RegulatorInspNoticeIssueCmd cmd) {
|
||||
InspNoticeEntity entity = new InspNoticeEntity();
|
||||
entity.setOrgId(cmd.getOrgId());
|
||||
entity.setInspTypeCode(cmd.getInspTypeCode());
|
||||
entity.setInspTypeName(cmd.getInspTypeName());
|
||||
entity.setSourceTypeCode(cmd.getSourceTypeCode());
|
||||
entity.setSourceTypeName(cmd.getSourceTypeName());
|
||||
entity.setSourceRefId(cmd.getSourceRefId());
|
||||
entity.setProjectId(cmd.getProjectId());
|
||||
entity.setPlanInspTime(cmd.getPlanInspTime());
|
||||
entity.setLeaderName(cmd.getLeaderName());
|
||||
entity.setNoticeContent(cmd.getNoticeContent());
|
||||
public SingleResponse<RegulatorInspNoticeCO> save(RegulatorInspNoticeSaveCmd cmd) {
|
||||
if (cmd.getId() != null) {
|
||||
InspNoticeEntity update = buildContentEntity(cmd);
|
||||
update.setId(InspNoticeIdSupport.parseNoticeId(cmd.getId()));
|
||||
InspNoticeEntity result = inspNoticeDomainService.updateDraft(update);
|
||||
return SingleResponse.success(toCO(result, resolveOrgName(result.getOrgId())));
|
||||
}
|
||||
Long orgId = InspNoticeIdSupport.parseOrgId(cmd.getOrgId());
|
||||
if (orgId == null) {
|
||||
throw new BizException(ErrorCode.REGULATOR_EVAL_PARAM_INVALID, "被检机构id不能为空");
|
||||
}
|
||||
InspNoticeEntity entity = buildContentEntity(cmd);
|
||||
entity.setOrgId(orgId);
|
||||
InspNoticeEntity result = saveDraftWithNoticeNo(entity);
|
||||
createPresetMaterials(result, cmd.getMaterialNames());
|
||||
return SingleResponse.success(toCO(result, resolveOrgName(result.getOrgId())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public SingleResponse<RegulatorInspNoticeCO> issue(RegulatorInspNoticeIssueCmd cmd) {
|
||||
if (cmd.getId() != null) {
|
||||
InspNoticeEntity result = inspNoticeDomainService.issueDraft(
|
||||
InspNoticeIdSupport.parseNoticeId(cmd.getId()));
|
||||
sendOrgMessage(result);
|
||||
return SingleResponse.success(toCO(result, resolveOrgName(result.getOrgId())));
|
||||
}
|
||||
Long orgId = InspNoticeIdSupport.parseOrgId(cmd.getOrgId());
|
||||
if (orgId == null) {
|
||||
throw new BizException(ErrorCode.REGULATOR_EVAL_PARAM_INVALID, "被检机构id不能为空");
|
||||
}
|
||||
InspNoticeEntity entity = new InspNoticeEntity();
|
||||
entity.setOrgId(orgId);
|
||||
fillContent(entity, cmd.getInspTypeCode(), cmd.getInspTypeName(), cmd.getSourceTypeCode(),
|
||||
cmd.getSourceTypeName(), cmd.getSourceRefId(), cmd.getSourceRefNo(), cmd.getProjectId(),
|
||||
cmd.getPlanInspTime(), cmd.getLeaderName(), cmd.getNoticeContent(),
|
||||
joinUrls(cmd.getNoticeUrls()), cmd.getRemarks());
|
||||
InspNoticeEntity result = issueWithNoticeNo(entity);
|
||||
createPresetMaterials(result, cmd.getMaterialNames());
|
||||
sendOrgMessage(result);
|
||||
return SingleResponse.success(toCO(result));
|
||||
return SingleResponse.success(toCO(result, resolveOrgName(result.getOrgId())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public SingleResponse<RegulatorInspNoticeCO> get(Long id) {
|
||||
return SingleResponse.success(toCO(inspNoticeDomainService.get(id)));
|
||||
InspNoticeEntity entity = inspNoticeDomainService.get(id);
|
||||
return SingleResponse.success(toCO(entity, resolveOrgName(entity.getOrgId())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageResponse<RegulatorInspNoticeCO> page(RegulatorInspNoticePageQuery query) {
|
||||
InspNoticeQuery domainQuery = new InspNoticeQuery();
|
||||
InspNoticeQuery domainQuery = regulatorInspNoticeFileSupport.toDomainQuery(query);
|
||||
if (domainQuery.getOrgIds() != null && domainQuery.getOrgIds().isEmpty()) {
|
||||
return PageResponse.of(Collections.<RegulatorInspNoticeCO>emptyList(), 0L);
|
||||
}
|
||||
domainQuery.setPageNum(query.getCurrent());
|
||||
domainQuery.setPageSize(query.getSize());
|
||||
domainQuery.setOrgId(query.getOrgId());
|
||||
domainQuery.setNoticeNo(query.getNoticeNo());
|
||||
domainQuery.setStatusCode(query.getStatusCode());
|
||||
domainQuery.setInspTypeCode(query.getInspTypeCode());
|
||||
domainQuery.setLeaderName(query.getLeaderName());
|
||||
PageResult<InspNoticeEntity> pageResult = inspNoticeDomainService.page(domainQuery);
|
||||
return PageResponse.of(
|
||||
pageResult.getRecords().stream().map(this::toCO).collect(Collectors.toList()),
|
||||
pageResult.getTotal());
|
||||
Map<Long, String> orgNameMap = buildOrgNameMap(pageResult.getRecords());
|
||||
List<RegulatorInspNoticeCO> list = pageResult.getRecords().stream()
|
||||
.map(entity -> toCO(entity, entity.getOrgId() == null ? null : orgNameMap.get(entity.getOrgId())))
|
||||
.collect(Collectors.toList());
|
||||
return PageResponse.of(list, pageResult.getTotal());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -100,14 +139,21 @@ public class RegulatorInspNoticeExecutor implements RegulatorInspNoticeApi {
|
|||
String recorderName = AuthUserContextAdapter.getCurrentUserName();
|
||||
String resultUrls = joinUrls(cmd.getResultUrls());
|
||||
InspNoticeEntity result = inspNoticeDomainService.close(
|
||||
cmd.getId(),
|
||||
InspNoticeIdSupport.parseNoticeId(cmd.getId()),
|
||||
cmd.getResultCode(),
|
||||
cmd.getResultName(),
|
||||
cmd.getResultContent(),
|
||||
resultUrls,
|
||||
recorderId,
|
||||
recorderName);
|
||||
return SingleResponse.success(toCO(result));
|
||||
return SingleResponse.success(toCO(result, resolveOrgName(result.getOrgId())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public SingleResponse<RegulatorInspNoticeCO> remark(RegulatorInspNoticeRemarkCmd cmd) {
|
||||
InspNoticeEntity result = inspNoticeDomainService.updateRemarks(
|
||||
InspNoticeIdSupport.parseNoticeId(cmd.getId()), cmd.getRemarks());
|
||||
return SingleResponse.success(toCO(result, resolveOrgName(result.getOrgId())));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -119,14 +165,86 @@ public class RegulatorInspNoticeExecutor implements RegulatorInspNoticeApi {
|
|||
|
||||
@Override
|
||||
public SingleResponse<Void> urge(RegulatorInspNoticeUrgeCmd cmd) {
|
||||
InspNoticeEntity notice = inspNoticeDomainService.get(cmd.getId());
|
||||
if (notice.getStatusCode() == null || notice.getStatusCode() >= InspNoticeDomainService.STATUS_CLOSED) {
|
||||
InspNoticeEntity notice = inspNoticeDomainService.get(
|
||||
InspNoticeIdSupport.parseNoticeId(cmd.getId()));
|
||||
Integer status = notice.getStatusCode();
|
||||
if (status == null
|
||||
|| status == InspNoticeDomainService.STATUS_DRAFT
|
||||
|| status >= InspNoticeDomainService.STATUS_CLOSED) {
|
||||
throw new BizException(ErrorCode.INSP_NOTICE_STATUS_INVALID);
|
||||
}
|
||||
sendOrgMessage(notice);
|
||||
return SingleResponse.success();
|
||||
}
|
||||
|
||||
private InspNoticeEntity buildContentEntity(RegulatorInspNoticeSaveCmd cmd) {
|
||||
InspNoticeEntity entity = new InspNoticeEntity();
|
||||
Long orgId = InspNoticeIdSupport.parseOrgId(cmd.getOrgId());
|
||||
if (orgId != null) {
|
||||
entity.setOrgId(orgId);
|
||||
}
|
||||
fillContent(entity, cmd.getInspTypeCode(), cmd.getInspTypeName(), cmd.getSourceTypeCode(),
|
||||
cmd.getSourceTypeName(), cmd.getSourceRefId(), cmd.getSourceRefNo(), cmd.getProjectId(),
|
||||
cmd.getPlanInspTime(), cmd.getLeaderName(), cmd.getNoticeContent(),
|
||||
joinUrls(cmd.getNoticeUrls()), cmd.getRemarks());
|
||||
return entity;
|
||||
}
|
||||
|
||||
private void fillContent(InspNoticeEntity entity, String inspTypeCode, String inspTypeName,
|
||||
Integer sourceTypeCode, String sourceTypeName, Long sourceRefId,
|
||||
String sourceRefNo, Long projectId, java.time.LocalDateTime planInspTime,
|
||||
String leaderName, String noticeContent, String noticeUrls, String remarks) {
|
||||
entity.setInspTypeCode(inspTypeCode);
|
||||
entity.setInspTypeName(inspTypeName);
|
||||
entity.setSourceTypeCode(sourceTypeCode);
|
||||
entity.setSourceTypeName(resolveSourceTypeName(sourceTypeCode, sourceTypeName));
|
||||
entity.setSourceRefId(sourceRefId);
|
||||
entity.setSourceRefNo(sourceRefNo);
|
||||
entity.setProjectId(projectId);
|
||||
entity.setPlanInspTime(planInspTime);
|
||||
entity.setLeaderName(leaderName);
|
||||
entity.setNoticeContent(noticeContent);
|
||||
entity.setNoticeUrls(noticeUrls);
|
||||
entity.setRemarks(remarks);
|
||||
}
|
||||
|
||||
private String resolveSourceTypeName(Integer code, String name) {
|
||||
if (StringUtils.hasText(name)) {
|
||||
return name.trim();
|
||||
}
|
||||
if (code == null) {
|
||||
return null;
|
||||
}
|
||||
switch (code) {
|
||||
case 1:
|
||||
return "年度计划";
|
||||
case 2:
|
||||
return "专项安排";
|
||||
case 3:
|
||||
return "其他";
|
||||
case 4:
|
||||
return "风险预警";
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private InspNoticeEntity saveDraftWithNoticeNo(InspNoticeEntity entity) {
|
||||
DuplicateKeyException lastEx = null;
|
||||
for (int i = 0; i < noticeNoGenerator.maxRetry(); i++) {
|
||||
entity.setNoticeNo(noticeNoGenerator.generate());
|
||||
try {
|
||||
return inspNoticeDomainService.saveDraft(entity);
|
||||
} catch (DuplicateKeyException ex) {
|
||||
lastEx = ex;
|
||||
}
|
||||
}
|
||||
if (lastEx != null) {
|
||||
throw new BizException(ErrorCode.INSP_NOTICE_NO_GENERATE_FAILED, lastEx);
|
||||
}
|
||||
throw new BizException(ErrorCode.INSP_NOTICE_NO_GENERATE_FAILED);
|
||||
}
|
||||
|
||||
private InspNoticeEntity issueWithNoticeNo(InspNoticeEntity entity) {
|
||||
DuplicateKeyException lastEx = null;
|
||||
for (int i = 0; i < noticeNoGenerator.maxRetry(); i++) {
|
||||
|
|
@ -183,26 +301,59 @@ public class RegulatorInspNoticeExecutor implements RegulatorInspNoticeApi {
|
|||
.collect(Collectors.joining(","));
|
||||
}
|
||||
|
||||
private RegulatorInspNoticeCO toCO(InspNoticeEntity entity) {
|
||||
private String resolveOrgName(Long orgId) {
|
||||
if (orgId == null || orgInfoGateway == null) {
|
||||
return null;
|
||||
}
|
||||
OrgInfoEntity org = orgInfoGateway.get(orgId);
|
||||
return org == null ? null : org.getUnitName();
|
||||
}
|
||||
|
||||
private Map<Long, String> buildOrgNameMap(List<InspNoticeEntity> records) {
|
||||
Map<Long, String> map = new HashMap<Long, String>();
|
||||
if (records == null || records.isEmpty() || orgInfoGateway == null) {
|
||||
return map;
|
||||
}
|
||||
Set<Long> ids = new HashSet<Long>();
|
||||
for (InspNoticeEntity entity : records) {
|
||||
if (entity != null && entity.getOrgId() != null) {
|
||||
ids.add(entity.getOrgId());
|
||||
}
|
||||
}
|
||||
for (Long id : ids) {
|
||||
OrgInfoEntity org = orgInfoGateway.get(id);
|
||||
if (org != null) {
|
||||
map.put(id, org.getUnitName());
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
private RegulatorInspNoticeCO toCO(InspNoticeEntity entity, String orgName) {
|
||||
if (entity == null) {
|
||||
return null;
|
||||
}
|
||||
RegulatorInspNoticeCO co = new RegulatorInspNoticeCO();
|
||||
co.setId(entity.getId() != null ? String.valueOf(entity.getId()) : null);
|
||||
co.setOrgId(entity.getOrgId() != null ? String.valueOf(entity.getOrgId()) : null);
|
||||
co.setOrgName(orgName);
|
||||
co.setNoticeNo(entity.getNoticeNo());
|
||||
co.setInspTypeCode(entity.getInspTypeCode());
|
||||
co.setInspTypeName(entity.getInspTypeName());
|
||||
co.setSourceTypeCode(entity.getSourceTypeCode());
|
||||
co.setSourceTypeName(entity.getSourceTypeName());
|
||||
co.setSourceRefId(entity.getSourceRefId() != null ? String.valueOf(entity.getSourceRefId()) : null);
|
||||
co.setSourceRefNo(entity.getSourceRefNo());
|
||||
co.setProjectId(entity.getProjectId() != null ? String.valueOf(entity.getProjectId()) : null);
|
||||
co.setPlanInspTime(entity.getPlanInspTime());
|
||||
co.setLeaderName(entity.getLeaderName());
|
||||
co.setNoticeContent(entity.getNoticeContent());
|
||||
co.setNoticeUrls(entity.getNoticeUrls());
|
||||
co.setStatusCode(entity.getStatusCode());
|
||||
co.setStatusName(entity.getStatusName());
|
||||
co.setConfirmFlag(entity.getConfirmFlag());
|
||||
co.setFeedbackFlag(entity.getStatusCode() != null && entity.getStatusCode() >= InspNoticeDomainService.STATUS_FEEDBACK
|
||||
? 1 : 2);
|
||||
co.setConfirmTime(entity.getConfirmTime());
|
||||
co.setSendTime(entity.getSendTime());
|
||||
co.setResultCode(entity.getResultCode());
|
||||
|
|
@ -211,6 +362,7 @@ public class RegulatorInspNoticeExecutor implements RegulatorInspNoticeApi {
|
|||
co.setResultUrls(entity.getResultUrls());
|
||||
co.setResultRecorderName(entity.getResultRecorderName());
|
||||
co.setResultTime(entity.getResultTime());
|
||||
co.setRemarks(entity.getRemarks());
|
||||
return co;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,208 @@
|
|||
package org.qinan.safetyeval.app.executor.support;
|
||||
|
||||
import org.qinan.safetyeval.client.dto.institution.InstitutionInspNoticeExportCmd;
|
||||
import org.qinan.safetyeval.domain.entity.InspNoticeEntity;
|
||||
import org.qinan.safetyeval.domain.exception.BizException;
|
||||
import org.qinan.safetyeval.domain.exception.ErrorCode;
|
||||
import org.qinan.safetyeval.domain.query.InspNoticeQuery;
|
||||
import org.qinan.safetyeval.domain.query.PageResult;
|
||||
import org.qinan.safetyeval.domain.service.InspNoticeDomainService;
|
||||
import org.qinan.safetyeval.infrastructure.support.InspNoticeIdSupport;
|
||||
import org.qinan.safetyeval.infrastructure.support.InstitutionOrgSupport;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 机构端监督检查通知:导出消息清单。
|
||||
*/
|
||||
@Component
|
||||
public class InstitutionInspNoticeFileSupport {
|
||||
|
||||
public static final int MAX_EXPORT_ROWS = 5000;
|
||||
private static final DateTimeFormatter DATE_FMT = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
||||
|
||||
@Lazy
|
||||
@Autowired(required = false)
|
||||
private InspNoticeDomainService inspNoticeDomainService;
|
||||
|
||||
@Lazy
|
||||
@Autowired(required = false)
|
||||
private InstitutionOrgSupport institutionOrgSupport;
|
||||
|
||||
public void writeMessageCsv(InstitutionInspNoticeExportCmd cmd, OutputStream outputStream) throws IOException {
|
||||
List<InspNoticeEntity> notices = resolveExportNotices(cmd);
|
||||
if (notices.isEmpty()) {
|
||||
throw new BizException(ErrorCode.INSP_NOTICE_EXPORT_EMPTY);
|
||||
}
|
||||
Writer writer = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8);
|
||||
try {
|
||||
writer.write('\ufeff');
|
||||
writer.write(csvLine(new String[]{
|
||||
"消息编号", "来源预警", "来源字段", "监管要求", "办理期限", "处理状态", "办结结果"
|
||||
}));
|
||||
for (InspNoticeEntity notice : notices) {
|
||||
if (notice == null) {
|
||||
continue;
|
||||
}
|
||||
writer.write(csvLine(new String[]{
|
||||
nullToEmpty(notice.getNoticeNo()),
|
||||
nullToEmpty(notice.getSourceRefNo()),
|
||||
sourceFieldLabel(notice),
|
||||
nullToEmpty(notice.getNoticeContent()),
|
||||
formatDate(notice.getPlanInspTime()),
|
||||
statusDisplayName(notice),
|
||||
resultLabel(notice)
|
||||
}));
|
||||
}
|
||||
writer.flush();
|
||||
} finally {
|
||||
writer.close();
|
||||
}
|
||||
}
|
||||
|
||||
private List<InspNoticeEntity> resolveExportNotices(InstitutionInspNoticeExportCmd cmd) {
|
||||
if (cmd == null) {
|
||||
throw new BizException(ErrorCode.INSP_NOTICE_EXPORT_EMPTY);
|
||||
}
|
||||
Long orgId = institutionOrgSupport.resolveCurrentOrgId();
|
||||
String scope = cmd.getScope() == null ? "" : cmd.getScope().trim().toUpperCase();
|
||||
boolean hasIds = !CollectionUtils.isEmpty(cmd.getIds());
|
||||
|
||||
if ("SELECTED".equals(scope) || (hasIds && !"FILTERED".equals(scope) && !"ALL".equals(scope))) {
|
||||
if (!hasIds) {
|
||||
throw new BizException(ErrorCode.INSP_NOTICE_EXPORT_EMPTY);
|
||||
}
|
||||
if (cmd.getIds().size() > MAX_EXPORT_ROWS) {
|
||||
throw new BizException(ErrorCode.INSP_NOTICE_EXPORT_TOO_LARGE);
|
||||
}
|
||||
List<Long> ids = new ArrayList<Long>();
|
||||
for (String raw : cmd.getIds()) {
|
||||
ids.add(InspNoticeIdSupport.parseNoticeId(raw));
|
||||
}
|
||||
InspNoticeQuery q = new InspNoticeQuery();
|
||||
q.setPageNum(1L);
|
||||
q.setPageSize((long) MAX_EXPORT_ROWS);
|
||||
q.setOrgId(orgId);
|
||||
q.setIds(ids);
|
||||
q.setMinStatusCode(InspNoticeDomainService.STATUS_ISSUED);
|
||||
PageResult<InspNoticeEntity> page = inspNoticeDomainService.page(q);
|
||||
return page == null || page.getRecords() == null
|
||||
? Collections.<InspNoticeEntity>emptyList()
|
||||
: page.getRecords();
|
||||
}
|
||||
|
||||
InspNoticeQuery query = new InspNoticeQuery();
|
||||
query.setOrgId(orgId);
|
||||
query.setPageNum(1L);
|
||||
query.setPageSize((long) MAX_EXPORT_ROWS);
|
||||
query.setMinStatusCode(InspNoticeDomainService.STATUS_ISSUED);
|
||||
if (!"ALL".equals(scope)) {
|
||||
query.setNoticeNo(cmd.getNoticeNo());
|
||||
query.setKeyword(cmd.getKeyword());
|
||||
query.setStatusCode(cmd.getStatusCode());
|
||||
query.setInspTypeCode(cmd.getInspTypeCode());
|
||||
query.setSourceTypeCode(cmd.getSourceTypeCode());
|
||||
query.setSourceRefNo(cmd.getSourceRefNo());
|
||||
query.setConfirmFlag(cmd.getConfirmFlag());
|
||||
query.setFeedbackFlag(cmd.getFeedbackFlag());
|
||||
if (cmd.getStatusCode() != null) {
|
||||
query.setMinStatusCode(null);
|
||||
}
|
||||
}
|
||||
PageResult<InspNoticeEntity> page = inspNoticeDomainService.page(query);
|
||||
if (page == null || page.getRecords() == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return page.getRecords();
|
||||
}
|
||||
|
||||
private static String sourceFieldLabel(InspNoticeEntity notice) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (StringUtils.hasText(notice.getSourceTypeName())) {
|
||||
sb.append(notice.getSourceTypeName());
|
||||
}
|
||||
if (StringUtils.hasText(notice.getInspTypeName())) {
|
||||
if (sb.length() > 0) {
|
||||
sb.append(' ');
|
||||
}
|
||||
sb.append(notice.getInspTypeName());
|
||||
}
|
||||
return sb.length() == 0 ? "监督检查" : sb.toString();
|
||||
}
|
||||
|
||||
private static String statusDisplayName(InspNoticeEntity notice) {
|
||||
Integer code = notice.getStatusCode();
|
||||
if (code == null) {
|
||||
return nullToEmpty(notice.getStatusName());
|
||||
}
|
||||
if (code == 1) {
|
||||
return "待处理";
|
||||
}
|
||||
if (code == 2) {
|
||||
return "处理中";
|
||||
}
|
||||
if (code == 3) {
|
||||
return "待监管复核";
|
||||
}
|
||||
if (code == 4) {
|
||||
return "已办结";
|
||||
}
|
||||
return nullToEmpty(notice.getStatusName());
|
||||
}
|
||||
|
||||
private static String resultLabel(InspNoticeEntity notice) {
|
||||
if (!StringUtils.hasText(notice.getResultName()) && !StringUtils.hasText(notice.getResultContent())) {
|
||||
return "";
|
||||
}
|
||||
if (!StringUtils.hasText(notice.getResultName())) {
|
||||
return nullToEmpty(notice.getResultContent());
|
||||
}
|
||||
if (!StringUtils.hasText(notice.getResultContent())) {
|
||||
return notice.getResultName();
|
||||
}
|
||||
return notice.getResultName() + ":" + notice.getResultContent();
|
||||
}
|
||||
|
||||
private static String formatDate(LocalDateTime value) {
|
||||
return value == null ? "" : DATE_FMT.format(value);
|
||||
}
|
||||
|
||||
private static String nullToEmpty(String value) {
|
||||
return value == null ? "" : value;
|
||||
}
|
||||
|
||||
private static String csvLine(String[] cols) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < cols.length; i++) {
|
||||
if (i > 0) {
|
||||
sb.append(',');
|
||||
}
|
||||
sb.append(escapeCsv(cols[i]));
|
||||
}
|
||||
sb.append('\n');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static String escapeCsv(String value) {
|
||||
if (value == null) {
|
||||
return "";
|
||||
}
|
||||
boolean needQuote = value.contains(",") || value.contains("\"") || value.contains("\n") || value.contains("\r");
|
||||
String escaped = value.replace("\"", "\"\"");
|
||||
return needQuote ? "\"" + escaped + "\"" : escaped;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,343 @@
|
|||
package org.qinan.safetyeval.app.executor.support;
|
||||
|
||||
import org.qinan.safetyeval.domain.entity.EvalReportEntity;
|
||||
import org.qinan.safetyeval.domain.entity.OrgInfoEntity;
|
||||
import org.qinan.safetyeval.domain.exception.BizException;
|
||||
import org.qinan.safetyeval.domain.exception.ErrorCode;
|
||||
import org.qinan.safetyeval.domain.gateway.OrgInfoGateway;
|
||||
import org.qinan.safetyeval.domain.query.EvalReportQuery;
|
||||
import org.qinan.safetyeval.domain.query.OrgInfoQuery;
|
||||
import org.qinan.safetyeval.domain.query.PageResult;
|
||||
import org.qinan.safetyeval.domain.service.EvalReportDomainService;
|
||||
import org.qinan.safetyeval.client.dto.regulator.RegulatorEvalReportExportCmd;
|
||||
import org.qinan.safetyeval.client.dto.regulator.RegulatorEvalReportPageQuery;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
/**
|
||||
* 监管端报告库:批量 ZIP 下载、目录 CSV 导出。
|
||||
*/
|
||||
@Component
|
||||
public class RegulatorEvalReportFileSupport {
|
||||
|
||||
public static final int MAX_BATCH_DOWNLOAD = 50;
|
||||
public static final int MAX_EXPORT_ROWS = 5000;
|
||||
private static final int CONNECT_TIMEOUT_MS = 15000;
|
||||
private static final int READ_TIMEOUT_MS = 60000;
|
||||
private static final DateTimeFormatter DATE_FMT = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
||||
private static final DateTimeFormatter DATETIME_FMT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
@Lazy
|
||||
@Autowired(required = false)
|
||||
private EvalReportDomainService evalReportDomainService;
|
||||
|
||||
@Autowired(required = false)
|
||||
private OrgInfoGateway orgInfoGateway;
|
||||
|
||||
public void writeBatchZip(List<Long> ids, OutputStream outputStream) throws IOException {
|
||||
if (ids == null || ids.isEmpty()) {
|
||||
throw new BizException(ErrorCode.EVAL_REPORT_BATCH_EMPTY);
|
||||
}
|
||||
if (ids.size() > MAX_BATCH_DOWNLOAD) {
|
||||
throw new BizException(ErrorCode.EVAL_REPORT_BATCH_TOO_LARGE);
|
||||
}
|
||||
List<EvalReportEntity> reports = evalReportDomainService.listByIds(ids);
|
||||
if (reports == null || reports.isEmpty()) {
|
||||
throw new BizException(ErrorCode.EVAL_REPORT_NOT_FOUND);
|
||||
}
|
||||
int withFile = 0;
|
||||
for (EvalReportEntity report : reports) {
|
||||
if (report != null && StringUtils.hasText(report.getFileUrl())) {
|
||||
withFile++;
|
||||
}
|
||||
}
|
||||
if (withFile == 0) {
|
||||
throw new BizException(ErrorCode.EVAL_REPORT_FILE_MISSING);
|
||||
}
|
||||
|
||||
Set<String> usedNames = new HashSet<String>();
|
||||
ZipOutputStream zip = new ZipOutputStream(outputStream);
|
||||
byte[] buffer = new byte[8192];
|
||||
try {
|
||||
for (EvalReportEntity report : reports) {
|
||||
if (report == null || !StringUtils.hasText(report.getFileUrl())) {
|
||||
continue;
|
||||
}
|
||||
String entryName = buildZipEntryName(report, usedNames);
|
||||
zip.putNextEntry(new ZipEntry(entryName));
|
||||
HttpURLConnection connection = null;
|
||||
InputStream in = null;
|
||||
try {
|
||||
connection = openConnection(report.getFileUrl().trim());
|
||||
in = new BufferedInputStream(connection.getInputStream());
|
||||
int n;
|
||||
while ((n = in.read(buffer)) != -1) {
|
||||
zip.write(buffer, 0, n);
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
// 单个文件失败写入说明条目,避免整包失败
|
||||
String tip = "下载失败: " + report.getFileUrl() + " / " + ex.getMessage();
|
||||
zip.write(tip.getBytes(StandardCharsets.UTF_8));
|
||||
} finally {
|
||||
if (in != null) {
|
||||
try {
|
||||
in.close();
|
||||
} catch (IOException ignore) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
if (connection != null) {
|
||||
connection.disconnect();
|
||||
}
|
||||
}
|
||||
zip.closeEntry();
|
||||
}
|
||||
zip.finish();
|
||||
} finally {
|
||||
zip.close();
|
||||
}
|
||||
}
|
||||
|
||||
public void writeCatalogCsv(RegulatorEvalReportExportCmd cmd, OutputStream outputStream) throws IOException {
|
||||
List<EvalReportEntity> reports = resolveExportReports(cmd);
|
||||
Map<Long, String> orgNameMap = buildOrgNameMap(reports);
|
||||
Writer writer = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8);
|
||||
try {
|
||||
// Excel UTF-8 BOM
|
||||
writer.write('\ufeff');
|
||||
writer.write(csvLine(new String[]{
|
||||
"报告编号", "报告名称", "报送机构", "评价类型", "所属行业",
|
||||
"被评价单位", "签发日期", "报送时间", "报告状态", "文件名", "文件地址"
|
||||
}));
|
||||
for (EvalReportEntity report : reports) {
|
||||
if (report == null) {
|
||||
continue;
|
||||
}
|
||||
String orgName = report.getOrgId() == null ? "" : orgNameMap.get(report.getOrgId());
|
||||
writer.write(csvLine(new String[]{
|
||||
nullToEmpty(report.getReportNo()),
|
||||
nullToEmpty(report.getReportName()),
|
||||
nullToEmpty(orgName),
|
||||
nullToEmpty(report.getEvalTypeName()),
|
||||
nullToEmpty(report.getIndustryName()),
|
||||
nullToEmpty(report.getEvaluatedUnitName()),
|
||||
formatDate(report.getIssueDate()),
|
||||
formatDateTime(report.getArchiveTime()),
|
||||
nullToEmpty(ReportProfileCoConverter.resolveDisplayStatusName(report)),
|
||||
nullToEmpty(report.getFileName()),
|
||||
nullToEmpty(report.getFileUrl())
|
||||
}));
|
||||
}
|
||||
writer.flush();
|
||||
} finally {
|
||||
writer.close();
|
||||
}
|
||||
}
|
||||
|
||||
private List<EvalReportEntity> resolveExportReports(RegulatorEvalReportExportCmd cmd) {
|
||||
if (cmd == null) {
|
||||
throw new BizException(ErrorCode.EVAL_REPORT_BATCH_EMPTY);
|
||||
}
|
||||
String scope = cmd.getScope() == null ? "" : cmd.getScope().trim().toUpperCase();
|
||||
boolean hasIds = cmd.getIds() != null && !cmd.getIds().isEmpty();
|
||||
if ("SELECTED".equals(scope) || (hasIds && !"FILTERED".equals(scope) && !"ALL".equals(scope))) {
|
||||
if (!hasIds) {
|
||||
throw new BizException(ErrorCode.EVAL_REPORT_BATCH_EMPTY);
|
||||
}
|
||||
if (cmd.getIds().size() > MAX_EXPORT_ROWS) {
|
||||
throw new BizException(ErrorCode.EVAL_REPORT_BATCH_TOO_LARGE);
|
||||
}
|
||||
return evalReportDomainService.listByIds(cmd.getIds());
|
||||
}
|
||||
|
||||
EvalReportQuery query = buildFilterQuery(cmd);
|
||||
if ("ALL".equals(scope)) {
|
||||
query.setReportYear(null);
|
||||
query.setEvalTypeCode(null);
|
||||
query.setIndustryCode(null);
|
||||
query.setKeyword(null);
|
||||
query.setReportStatusCode(null);
|
||||
query.setArchiveTimeFrom(null);
|
||||
query.setArchiveTimeTo(null);
|
||||
query.setOrgId(null);
|
||||
query.setOrgIds(null);
|
||||
}
|
||||
query.setSubmitFlag(cmd.getSubmitFlag() != null ? cmd.getSubmitFlag() : 1);
|
||||
query.setPageNum(1L);
|
||||
query.setPageSize((long) MAX_EXPORT_ROWS);
|
||||
PageResult<EvalReportEntity> page = evalReportDomainService.page(query);
|
||||
if (page == null || page.getRecords() == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return page.getRecords();
|
||||
}
|
||||
|
||||
private EvalReportQuery buildFilterQuery(RegulatorEvalReportPageQuery query) {
|
||||
EvalReportQuery domainQuery = new EvalReportQuery();
|
||||
domainQuery.setOrgId(query.getOrgId());
|
||||
domainQuery.setReportYear(query.getReportYear());
|
||||
domainQuery.setEvalTypeCode(query.getEvalTypeCode());
|
||||
domainQuery.setIndustryCode(query.getIndustryCode());
|
||||
domainQuery.setReportStatusCode(query.getReportStatusCode());
|
||||
domainQuery.setKeyword(query.getKeyword());
|
||||
domainQuery.setSubmitFlag(query.getSubmitFlag() != null ? query.getSubmitFlag() : 1);
|
||||
if (StringUtils.hasText(query.getArchiveTimeStart())) {
|
||||
domainQuery.setArchiveTimeFrom(LocalDate.parse(query.getArchiveTimeStart().trim()).atStartOfDay());
|
||||
}
|
||||
if (StringUtils.hasText(query.getArchiveTimeEnd())) {
|
||||
domainQuery.setArchiveTimeTo(LocalDate.parse(query.getArchiveTimeEnd().trim()).atTime(LocalTime.MAX));
|
||||
}
|
||||
if (StringUtils.hasText(query.getOrgName())) {
|
||||
domainQuery.setOrgIds(resolveOrgIdsByName(query.getOrgName().trim()));
|
||||
}
|
||||
return domainQuery;
|
||||
}
|
||||
|
||||
private List<Long> resolveOrgIdsByName(String orgName) {
|
||||
if (orgInfoGateway == null || !StringUtils.hasText(orgName)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
OrgInfoQuery query = new OrgInfoQuery();
|
||||
query.setPageNum(1L);
|
||||
query.setPageSize(500L);
|
||||
query.setUnitName(orgName);
|
||||
PageResult<OrgInfoEntity> page = orgInfoGateway.page(query);
|
||||
if (page == null || page.getRecords() == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<Long> ids = new ArrayList<Long>();
|
||||
for (OrgInfoEntity org : page.getRecords()) {
|
||||
if (org != null && org.getId() != null) {
|
||||
ids.add(org.getId());
|
||||
}
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
|
||||
private Map<Long, String> buildOrgNameMap(List<EvalReportEntity> records) {
|
||||
Map<Long, String> map = new HashMap<Long, String>();
|
||||
if (records == null || records.isEmpty() || orgInfoGateway == null) {
|
||||
return map;
|
||||
}
|
||||
Set<Long> ids = new HashSet<Long>();
|
||||
for (EvalReportEntity entity : records) {
|
||||
if (entity != null && entity.getOrgId() != null) {
|
||||
ids.add(entity.getOrgId());
|
||||
}
|
||||
}
|
||||
for (Long id : ids) {
|
||||
OrgInfoEntity org = orgInfoGateway.get(id);
|
||||
if (org != null) {
|
||||
map.put(id, org.getUnitName());
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
private HttpURLConnection openConnection(String fileUrl) throws IOException {
|
||||
URL url = new URL(fileUrl);
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setConnectTimeout(CONNECT_TIMEOUT_MS);
|
||||
connection.setReadTimeout(READ_TIMEOUT_MS);
|
||||
connection.setInstanceFollowRedirects(true);
|
||||
connection.setRequestMethod("GET");
|
||||
int code = connection.getResponseCode();
|
||||
if (code >= 400) {
|
||||
throw new IOException("HTTP " + code);
|
||||
}
|
||||
return connection;
|
||||
}
|
||||
|
||||
private String buildZipEntryName(EvalReportEntity report, Set<String> usedNames) {
|
||||
String base = StringUtils.hasText(report.getReportNo())
|
||||
? report.getReportNo().trim()
|
||||
: ("report-" + report.getId());
|
||||
base = base.replaceAll("[\\\\/:*?\"<>|]", "_");
|
||||
String ext = extractExtension(report.getFileName(), report.getFileUrl());
|
||||
String name = base + ext;
|
||||
int i = 2;
|
||||
while (!usedNames.add(name)) {
|
||||
name = base + "_" + i + ext;
|
||||
i++;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
private String extractExtension(String fileName, String fileUrl) {
|
||||
String source = StringUtils.hasText(fileName) ? fileName : fileUrl;
|
||||
if (!StringUtils.hasText(source)) {
|
||||
return ".bin";
|
||||
}
|
||||
int q = source.indexOf('?');
|
||||
if (q > 0) {
|
||||
source = source.substring(0, q);
|
||||
}
|
||||
int dot = source.lastIndexOf('.');
|
||||
int slash = Math.max(source.lastIndexOf('/'), source.lastIndexOf('\\'));
|
||||
if (dot > slash && dot < source.length() - 1) {
|
||||
String ext = source.substring(dot);
|
||||
if (ext.length() <= 10) {
|
||||
return ext;
|
||||
}
|
||||
}
|
||||
return ".bin";
|
||||
}
|
||||
|
||||
private String csvLine(String[] cols) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < cols.length; i++) {
|
||||
if (i > 0) {
|
||||
sb.append(',');
|
||||
}
|
||||
sb.append(csvEscape(cols[i]));
|
||||
}
|
||||
sb.append('\n');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String csvEscape(String value) {
|
||||
if (value == null) {
|
||||
return "";
|
||||
}
|
||||
boolean needQuote = value.contains(",") || value.contains("\"") || value.contains("\n") || value.contains("\r");
|
||||
String escaped = value.replace("\"", "\"\"");
|
||||
return needQuote ? ("\"" + escaped + "\"") : escaped;
|
||||
}
|
||||
|
||||
private String nullToEmpty(String value) {
|
||||
return value == null ? "" : value;
|
||||
}
|
||||
|
||||
private String formatDate(LocalDate date) {
|
||||
return date == null ? "" : DATE_FMT.format(date);
|
||||
}
|
||||
|
||||
private String formatDateTime(LocalDateTime dateTime) {
|
||||
return dateTime == null ? "" : DATETIME_FMT.format(dateTime);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,312 @@
|
|||
package org.qinan.safetyeval.app.executor.support;
|
||||
|
||||
import org.qinan.safetyeval.client.dto.regulator.RegulatorInspNoticeExportCmd;
|
||||
import org.qinan.safetyeval.client.dto.regulator.RegulatorInspNoticePageQuery;
|
||||
import org.qinan.safetyeval.domain.entity.InspNoticeEntity;
|
||||
import org.qinan.safetyeval.domain.entity.InspNoticeMaterialEntity;
|
||||
import org.qinan.safetyeval.domain.entity.OrgInfoEntity;
|
||||
import org.qinan.safetyeval.domain.exception.BizException;
|
||||
import org.qinan.safetyeval.domain.exception.ErrorCode;
|
||||
import org.qinan.safetyeval.domain.gateway.OrgInfoGateway;
|
||||
import org.qinan.safetyeval.domain.query.InspNoticeQuery;
|
||||
import org.qinan.safetyeval.domain.query.OrgInfoQuery;
|
||||
import org.qinan.safetyeval.domain.query.PageResult;
|
||||
import org.qinan.safetyeval.domain.service.InspNoticeDomainService;
|
||||
import org.qinan.safetyeval.domain.service.InspNoticeMaterialDomainService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 监管端监督检查告知:导出台账、下载单条检查记录。
|
||||
*/
|
||||
@Component
|
||||
public class RegulatorInspNoticeFileSupport {
|
||||
|
||||
public static final int MAX_EXPORT_ROWS = 5000;
|
||||
private static final DateTimeFormatter DATETIME_FMT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
@Lazy
|
||||
@Autowired(required = false)
|
||||
private InspNoticeDomainService inspNoticeDomainService;
|
||||
|
||||
@Lazy
|
||||
@Autowired(required = false)
|
||||
private InspNoticeMaterialDomainService inspNoticeMaterialDomainService;
|
||||
|
||||
@Autowired(required = false)
|
||||
private OrgInfoGateway orgInfoGateway;
|
||||
|
||||
public void writeLedgerCsv(RegulatorInspNoticeExportCmd cmd, OutputStream outputStream) throws IOException {
|
||||
List<InspNoticeEntity> notices = resolveExportNotices(cmd);
|
||||
if (notices.isEmpty()) {
|
||||
throw new BizException(ErrorCode.INSP_NOTICE_EXPORT_EMPTY);
|
||||
}
|
||||
Map<Long, String> orgNameMap = buildOrgNameMap(notices);
|
||||
Writer writer = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8);
|
||||
try {
|
||||
writer.write('\ufeff');
|
||||
writer.write(csvLine(new String[]{
|
||||
"告知编号", "评价机构", "检查类型", "计划检查时间", "来源方式", "来源预警编号",
|
||||
"检查负责人", "机构确认", "材料反馈", "办理状态", "下发时间", "检查结果", "结果说明"
|
||||
}));
|
||||
for (InspNoticeEntity notice : notices) {
|
||||
if (notice == null) {
|
||||
continue;
|
||||
}
|
||||
String orgName = notice.getOrgId() == null ? "" : nullToEmpty(orgNameMap.get(notice.getOrgId()));
|
||||
writer.write(csvLine(new String[]{
|
||||
nullToEmpty(notice.getNoticeNo()),
|
||||
orgName,
|
||||
nullToEmpty(notice.getInspTypeName()),
|
||||
formatDateTime(notice.getPlanInspTime()),
|
||||
nullToEmpty(notice.getSourceTypeName()),
|
||||
nullToEmpty(notice.getSourceRefNo()),
|
||||
nullToEmpty(notice.getLeaderName()),
|
||||
confirmLabel(notice.getConfirmFlag()),
|
||||
feedbackLabel(notice.getStatusCode()),
|
||||
nullToEmpty(notice.getStatusName()),
|
||||
formatDateTime(notice.getSendTime()),
|
||||
nullToEmpty(notice.getResultName()),
|
||||
nullToEmpty(notice.getResultContent())
|
||||
}));
|
||||
}
|
||||
writer.flush();
|
||||
} finally {
|
||||
writer.close();
|
||||
}
|
||||
}
|
||||
|
||||
public void writeRecordCsv(Long id, OutputStream outputStream) throws IOException {
|
||||
InspNoticeEntity notice = inspNoticeDomainService.get(id);
|
||||
String orgName = "";
|
||||
if (notice.getOrgId() != null && orgInfoGateway != null) {
|
||||
OrgInfoEntity org = orgInfoGateway.get(notice.getOrgId());
|
||||
if (org != null) {
|
||||
orgName = nullToEmpty(org.getUnitName());
|
||||
}
|
||||
}
|
||||
List<InspNoticeMaterialEntity> materials = inspNoticeMaterialDomainService == null
|
||||
? Collections.<InspNoticeMaterialEntity>emptyList()
|
||||
: inspNoticeMaterialDomainService.listByNoticeId(id);
|
||||
|
||||
Writer writer = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8);
|
||||
try {
|
||||
writer.write('\ufeff');
|
||||
writer.write(csvLine(new String[]{"字段", "内容"}));
|
||||
writeKv(writer, "告知编号", notice.getNoticeNo());
|
||||
writeKv(writer, "评价机构", orgName);
|
||||
writeKv(writer, "检查类型", notice.getInspTypeName());
|
||||
writeKv(writer, "计划检查时间", formatDateTime(notice.getPlanInspTime()));
|
||||
writeKv(writer, "来源方式", notice.getSourceTypeName());
|
||||
writeKv(writer, "来源预警编号", notice.getSourceRefNo());
|
||||
writeKv(writer, "检查负责人", notice.getLeaderName());
|
||||
writeKv(writer, "告知内容", notice.getNoticeContent());
|
||||
writeKv(writer, "告知附件", notice.getNoticeUrls());
|
||||
writeKv(writer, "机构确认", confirmLabel(notice.getConfirmFlag()));
|
||||
writeKv(writer, "确认时间", formatDateTime(notice.getConfirmTime()));
|
||||
writeKv(writer, "材料反馈", feedbackLabel(notice.getStatusCode()));
|
||||
writeKv(writer, "办理状态", notice.getStatusName());
|
||||
writeKv(writer, "下发时间", formatDateTime(notice.getSendTime()));
|
||||
writeKv(writer, "检查结果", notice.getResultName());
|
||||
writeKv(writer, "结果说明", notice.getResultContent());
|
||||
writeKv(writer, "结果附件", notice.getResultUrls());
|
||||
writeKv(writer, "结果登记人", notice.getResultRecorderName());
|
||||
writeKv(writer, "结果登记时间", formatDateTime(notice.getResultTime()));
|
||||
writeKv(writer, "监管备注", notice.getRemarks());
|
||||
writer.write(csvLine(new String[]{"材料名称", "上传状态", "文件地址"}));
|
||||
for (InspNoticeMaterialEntity material : materials) {
|
||||
if (material == null) {
|
||||
continue;
|
||||
}
|
||||
writer.write(csvLine(new String[]{
|
||||
nullToEmpty(material.getMaterialName()),
|
||||
nullToEmpty(material.getUploadStatusName()),
|
||||
nullToEmpty(material.getFileUrl())
|
||||
}));
|
||||
}
|
||||
writer.flush();
|
||||
} finally {
|
||||
writer.close();
|
||||
}
|
||||
}
|
||||
|
||||
public InspNoticeQuery toDomainQuery(RegulatorInspNoticePageQuery query) {
|
||||
InspNoticeQuery domainQuery = new InspNoticeQuery();
|
||||
domainQuery.setOrgId(query.getOrgId());
|
||||
domainQuery.setNoticeNo(query.getNoticeNo());
|
||||
domainQuery.setKeyword(query.getKeyword());
|
||||
domainQuery.setStatusCode(query.getStatusCode());
|
||||
domainQuery.setInspTypeCode(query.getInspTypeCode());
|
||||
domainQuery.setLeaderName(query.getLeaderName());
|
||||
domainQuery.setSourceTypeCode(query.getSourceTypeCode());
|
||||
domainQuery.setSourceRefNo(query.getSourceRefNo());
|
||||
domainQuery.setConfirmFlag(query.getConfirmFlag());
|
||||
domainQuery.setFeedbackFlag(query.getFeedbackFlag());
|
||||
if (StringUtils.hasText(query.getPlanInspTimeStart())) {
|
||||
domainQuery.setPlanInspTimeFrom(LocalDate.parse(query.getPlanInspTimeStart().trim()).atStartOfDay());
|
||||
}
|
||||
if (StringUtils.hasText(query.getPlanInspTimeEnd())) {
|
||||
domainQuery.setPlanInspTimeTo(LocalDate.parse(query.getPlanInspTimeEnd().trim()).atTime(LocalTime.MAX));
|
||||
}
|
||||
if (StringUtils.hasText(query.getOrgName())) {
|
||||
domainQuery.setOrgIds(resolveOrgIdsByName(query.getOrgName().trim()));
|
||||
}
|
||||
return domainQuery;
|
||||
}
|
||||
|
||||
private List<InspNoticeEntity> resolveExportNotices(RegulatorInspNoticeExportCmd cmd) {
|
||||
if (cmd == null) {
|
||||
throw new BizException(ErrorCode.INSP_NOTICE_EXPORT_EMPTY);
|
||||
}
|
||||
String scope = cmd.getScope() == null ? "" : cmd.getScope().trim().toUpperCase();
|
||||
boolean hasIds = cmd.getIds() != null && !cmd.getIds().isEmpty();
|
||||
if ("SELECTED".equals(scope) || (hasIds && !"FILTERED".equals(scope) && !"ALL".equals(scope))) {
|
||||
if (!hasIds) {
|
||||
throw new BizException(ErrorCode.INSP_NOTICE_EXPORT_EMPTY);
|
||||
}
|
||||
if (cmd.getIds().size() > MAX_EXPORT_ROWS) {
|
||||
throw new BizException(ErrorCode.INSP_NOTICE_EXPORT_TOO_LARGE);
|
||||
}
|
||||
InspNoticeQuery q = new InspNoticeQuery();
|
||||
q.setPageNum(1L);
|
||||
q.setPageSize((long) MAX_EXPORT_ROWS);
|
||||
q.setIds(cmd.getIds());
|
||||
PageResult<InspNoticeEntity> page = inspNoticeDomainService.page(q);
|
||||
return page == null || page.getRecords() == null ? Collections.<InspNoticeEntity>emptyList() : page.getRecords();
|
||||
}
|
||||
|
||||
InspNoticeQuery query = toDomainQuery(cmd);
|
||||
if ("ALL".equals(scope)) {
|
||||
query.setOrgId(null);
|
||||
query.setOrgIds(null);
|
||||
query.setNoticeNo(null);
|
||||
query.setKeyword(null);
|
||||
query.setStatusCode(null);
|
||||
query.setInspTypeCode(null);
|
||||
query.setLeaderName(null);
|
||||
query.setSourceTypeCode(null);
|
||||
query.setSourceRefNo(null);
|
||||
query.setPlanInspTimeFrom(null);
|
||||
query.setPlanInspTimeTo(null);
|
||||
query.setConfirmFlag(null);
|
||||
query.setFeedbackFlag(null);
|
||||
}
|
||||
if (query.getOrgIds() != null && query.getOrgIds().isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
query.setPageNum(1L);
|
||||
query.setPageSize((long) MAX_EXPORT_ROWS);
|
||||
PageResult<InspNoticeEntity> page = inspNoticeDomainService.page(query);
|
||||
if (page == null || page.getRecords() == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return page.getRecords();
|
||||
}
|
||||
|
||||
private List<Long> resolveOrgIdsByName(String orgName) {
|
||||
if (orgInfoGateway == null || !StringUtils.hasText(orgName)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
OrgInfoQuery query = new OrgInfoQuery();
|
||||
query.setPageNum(1L);
|
||||
query.setPageSize(500L);
|
||||
query.setUnitName(orgName);
|
||||
PageResult<OrgInfoEntity> page = orgInfoGateway.page(query);
|
||||
if (page == null || page.getRecords() == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<Long> ids = new ArrayList<Long>();
|
||||
for (OrgInfoEntity org : page.getRecords()) {
|
||||
if (org != null && org.getId() != null) {
|
||||
ids.add(org.getId());
|
||||
}
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
|
||||
private Map<Long, String> buildOrgNameMap(List<InspNoticeEntity> records) {
|
||||
Map<Long, String> map = new HashMap<Long, String>();
|
||||
if (records == null || records.isEmpty() || orgInfoGateway == null) {
|
||||
return map;
|
||||
}
|
||||
Set<Long> ids = new HashSet<Long>();
|
||||
for (InspNoticeEntity entity : records) {
|
||||
if (entity != null && entity.getOrgId() != null) {
|
||||
ids.add(entity.getOrgId());
|
||||
}
|
||||
}
|
||||
for (Long id : ids) {
|
||||
OrgInfoEntity org = orgInfoGateway.get(id);
|
||||
if (org != null) {
|
||||
map.put(id, org.getUnitName());
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
private void writeKv(Writer writer, String key, String value) throws IOException {
|
||||
writer.write(csvLine(new String[]{key, nullToEmpty(value)}));
|
||||
}
|
||||
|
||||
private static String confirmLabel(Integer confirmFlag) {
|
||||
if (confirmFlag != null && confirmFlag == 1) {
|
||||
return "已确认";
|
||||
}
|
||||
return "未确认";
|
||||
}
|
||||
|
||||
private static String feedbackLabel(Integer statusCode) {
|
||||
if (statusCode != null && statusCode >= InspNoticeDomainService.STATUS_FEEDBACK) {
|
||||
return "已提交";
|
||||
}
|
||||
return "未提交";
|
||||
}
|
||||
|
||||
private static String formatDateTime(LocalDateTime value) {
|
||||
return value == null ? "" : DATETIME_FMT.format(value);
|
||||
}
|
||||
|
||||
private static String nullToEmpty(String value) {
|
||||
return value == null ? "" : value;
|
||||
}
|
||||
|
||||
private static String csvLine(String[] cols) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < cols.length; i++) {
|
||||
if (i > 0) {
|
||||
sb.append(',');
|
||||
}
|
||||
sb.append(escapeCsv(cols[i]));
|
||||
}
|
||||
sb.append('\n');
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static String escapeCsv(String value) {
|
||||
if (value == null) {
|
||||
return "";
|
||||
}
|
||||
boolean needQuote = value.contains(",") || value.contains("\"") || value.contains("\n") || value.contains("\r");
|
||||
String escaped = value.replace("\"", "\"\"");
|
||||
return needQuote ? "\"" + escaped + "\"" : escaped;
|
||||
}
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ import org.qinan.safetyeval.client.co.report.EvalReportSpotcheckCO;
|
|||
import org.qinan.safetyeval.domain.entity.EvalReportEntity;
|
||||
import org.qinan.safetyeval.domain.entity.EvalReportSpotcheckEntity;
|
||||
import org.qinan.safetyeval.domain.entity.OrgProfileScoreEntity;
|
||||
import org.qinan.safetyeval.domain.service.EvalReportDomainService;
|
||||
|
||||
public final class ReportProfileCoConverter {
|
||||
|
||||
|
|
@ -19,24 +20,58 @@ public final class ReportProfileCoConverter {
|
|||
EvalReportLibraryCO co = new EvalReportLibraryCO();
|
||||
co.setId(entity.getId() != null ? String.valueOf(entity.getId()) : null);
|
||||
co.setOrgId(entity.getOrgId() != null ? String.valueOf(entity.getOrgId()) : null);
|
||||
co.setOrgName(null);
|
||||
co.setProjectId(entity.getProjectId() != null ? String.valueOf(entity.getProjectId()) : null);
|
||||
co.setCustomerId(entity.getCustomerId() != null ? String.valueOf(entity.getCustomerId()) : null);
|
||||
co.setEvaluatedUnitName(entity.getEvaluatedUnitName());
|
||||
co.setReportNo(entity.getReportNo());
|
||||
co.setReportName(entity.getReportName());
|
||||
co.setReportYear(entity.getReportYear());
|
||||
co.setEvalTypeCode(entity.getEvalTypeCode());
|
||||
co.setEvalTypeName(entity.getEvalTypeName());
|
||||
co.setIndustryCode(entity.getIndustryCode());
|
||||
co.setIndustryName(entity.getIndustryName());
|
||||
co.setBusinessScope(entity.getBusinessScope());
|
||||
co.setFileUrl(entity.getFileUrl());
|
||||
co.setFileName(entity.getFileName());
|
||||
co.setPublicFlag(entity.getPublicFlag());
|
||||
co.setCompleteFlag(entity.getCompleteFlag());
|
||||
co.setSubmitFlag(entity.getSubmitFlag());
|
||||
co.setReportStatusCode(entity.getReportStatusCode());
|
||||
co.setReportStatusName(entity.getReportStatusName());
|
||||
co.setDisplayStatusName(resolveDisplayStatusName(entity));
|
||||
co.setArchiveTime(entity.getArchiveTime());
|
||||
co.setIssueDate(entity.getIssueDate());
|
||||
co.setPageCount(entity.getPageCount());
|
||||
co.setSecretLevelCode(entity.getSecretLevelCode());
|
||||
co.setSecretLevelName(entity.getSecretLevelName());
|
||||
co.setRemarks(entity.getRemarks());
|
||||
return co;
|
||||
}
|
||||
|
||||
/**
|
||||
* 原型列表「报送状态」展示:未报送 / 已报送 / 抽查中 / 整改中 / 已复核
|
||||
*/
|
||||
public static String resolveDisplayStatusName(EvalReportEntity entity) {
|
||||
if (entity == null) {
|
||||
return null;
|
||||
}
|
||||
Integer status = entity.getReportStatusCode();
|
||||
if (status != null && status == EvalReportDomainService.STATUS_SPOTCHECKING) {
|
||||
return "抽查中";
|
||||
}
|
||||
if (status != null && status == EvalReportDomainService.STATUS_RECTIFY) {
|
||||
return "整改中";
|
||||
}
|
||||
if (status != null && status == EvalReportDomainService.STATUS_REVIEWED) {
|
||||
return "已复核";
|
||||
}
|
||||
if (entity.getSubmitFlag() != null && entity.getSubmitFlag() == 2) {
|
||||
return "未报送";
|
||||
}
|
||||
return "已报送";
|
||||
}
|
||||
|
||||
public static EvalReportSpotcheckCO toSpotcheckCO(EvalReportSpotcheckEntity entity) {
|
||||
if (entity == null) {
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -1,13 +1,22 @@
|
|||
package org.qinan.safetyeval.client.api.institution;
|
||||
|
||||
import org.qinan.safetyeval.client.co.report.EvalReportLibraryCO;
|
||||
import org.qinan.safetyeval.client.co.report.InstitutionEvalReportSummaryCO;
|
||||
import org.qinan.safetyeval.client.dto.PageResponse;
|
||||
import org.qinan.safetyeval.client.dto.SingleResponse;
|
||||
import org.qinan.safetyeval.client.dto.institution.InstitutionEvalReportAddCmd;
|
||||
import org.qinan.safetyeval.client.dto.institution.InstitutionEvalReportPageQuery;
|
||||
import org.qinan.safetyeval.client.dto.institution.InstitutionEvalReportSubmitCmd;
|
||||
|
||||
public interface InstitutionEvalReportApi {
|
||||
|
||||
PageResponse<EvalReportLibraryCO> page(InstitutionEvalReportPageQuery query);
|
||||
|
||||
SingleResponse<EvalReportLibraryCO> get(Long id);
|
||||
|
||||
SingleResponse<InstitutionEvalReportSummaryCO> summary();
|
||||
|
||||
SingleResponse<EvalReportLibraryCO> add(InstitutionEvalReportAddCmd cmd);
|
||||
|
||||
SingleResponse<EvalReportLibraryCO> submit(InstitutionEvalReportSubmitCmd cmd);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package org.qinan.safetyeval.client.api.regulator;
|
||||
|
||||
import org.qinan.safetyeval.client.co.report.EvalReportLibraryCO;
|
||||
import org.qinan.safetyeval.client.co.report.RegulatorEvalReportSummaryCO;
|
||||
import org.qinan.safetyeval.client.dto.PageResponse;
|
||||
import org.qinan.safetyeval.client.dto.SingleResponse;
|
||||
import org.qinan.safetyeval.client.dto.regulator.RegulatorEvalReportAddCmd;
|
||||
|
|
@ -8,6 +9,8 @@ import org.qinan.safetyeval.client.dto.regulator.RegulatorEvalReportPageQuery;
|
|||
|
||||
public interface RegulatorEvalReportApi {
|
||||
|
||||
SingleResponse<RegulatorEvalReportSummaryCO> summary();
|
||||
|
||||
PageResponse<EvalReportLibraryCO> page(RegulatorEvalReportPageQuery query);
|
||||
|
||||
SingleResponse<EvalReportLibraryCO> get(Long id);
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@ import java.util.List;
|
|||
|
||||
public interface RegulatorInspNoticeApi {
|
||||
|
||||
SingleResponse<RegulatorInspNoticeCO> save(RegulatorInspNoticeSaveCmd cmd);
|
||||
|
||||
SingleResponse<RegulatorInspNoticeCO> issue(RegulatorInspNoticeIssueCmd cmd);
|
||||
|
||||
SingleResponse<RegulatorInspNoticeCO> get(Long id);
|
||||
|
|
@ -18,6 +20,8 @@ public interface RegulatorInspNoticeApi {
|
|||
|
||||
SingleResponse<RegulatorInspNoticeCO> close(RegulatorInspNoticeCloseCmd cmd);
|
||||
|
||||
SingleResponse<RegulatorInspNoticeCO> remark(RegulatorInspNoticeRemarkCmd cmd);
|
||||
|
||||
SingleResponse<List<InspNoticeMaterialCO>> materials(Long noticeId);
|
||||
|
||||
SingleResponse<Void> urge(RegulatorInspNoticeUrgeCmd cmd);
|
||||
|
|
|
|||
|
|
@ -20,12 +20,15 @@ public class InstitutionInspNoticeCO {
|
|||
@ApiModelProperty(value = "检查类型名称:项目过程检查/资质保持检查/专项检查", example = "项目过程检查")
|
||||
private String inspTypeName;
|
||||
|
||||
@ApiModelProperty(value = "来源方式编码:1年度计划 2专项安排 3其他", example = "1")
|
||||
@ApiModelProperty(value = "来源方式编码:1年度计划 2专项安排 3其他 4风险预警", example = "4")
|
||||
private Integer sourceTypeCode;
|
||||
|
||||
@ApiModelProperty(value = "来源方式名称:年度计划/专项安排/其他", example = "年度计划")
|
||||
@ApiModelProperty(value = "来源方式名称:年度计划/专项安排/其他/风险预警", example = "风险预警")
|
||||
private String sourceTypeName;
|
||||
|
||||
@ApiModelProperty("来源预警/业务编号")
|
||||
private String sourceRefNo;
|
||||
|
||||
@ApiModelProperty("计划检查时间")
|
||||
private LocalDateTime planInspTime;
|
||||
|
||||
|
|
@ -35,7 +38,10 @@ public class InstitutionInspNoticeCO {
|
|||
@ApiModelProperty("告知内容")
|
||||
private String noticeContent;
|
||||
|
||||
@ApiModelProperty(value = "状态编码:1已下发 2已确认 3已反馈 4已办结", example = "1")
|
||||
@ApiModelProperty("告知附件URL,逗号分隔")
|
||||
private String noticeUrls;
|
||||
|
||||
@ApiModelProperty(value = "状态编码:1已下发 2已确认 3已反馈 4已办结(机构端不见草稿)", example = "1")
|
||||
private Integer statusCode;
|
||||
|
||||
@ApiModelProperty(value = "状态名称:已下发/已确认/已反馈/已办结", example = "已下发")
|
||||
|
|
@ -44,16 +50,19 @@ public class InstitutionInspNoticeCO {
|
|||
@ApiModelProperty(value = "机构是否确认:1是 2否", example = "2")
|
||||
private Integer confirmFlag;
|
||||
|
||||
@ApiModelProperty(value = "材料反馈:1已提交 2未提交", example = "2")
|
||||
private Integer feedbackFlag;
|
||||
|
||||
@ApiModelProperty("确认时间")
|
||||
private LocalDateTime confirmTime;
|
||||
|
||||
@ApiModelProperty("下发时间")
|
||||
private LocalDateTime sendTime;
|
||||
|
||||
@ApiModelProperty(value = "检查结果编码:1合格 2不合格 3限期整改", example = "1")
|
||||
@ApiModelProperty(value = "检查结果编码:1未发现问题/合格 2责令整改/不合格 3转入风险预警/限期整改", example = "1")
|
||||
private Integer resultCode;
|
||||
|
||||
@ApiModelProperty(value = "检查结果名称:合格/不合格/限期整改", example = "合格")
|
||||
@ApiModelProperty(value = "检查结果名称", example = "未发现问题")
|
||||
private String resultName;
|
||||
|
||||
@ApiModelProperty("结果说明")
|
||||
|
|
@ -64,4 +73,7 @@ public class InstitutionInspNoticeCO {
|
|||
|
||||
@ApiModelProperty("结果登记时间")
|
||||
private LocalDateTime resultTime;
|
||||
|
||||
@ApiModelProperty("监管备注")
|
||||
private String remarks;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,9 @@ public class RegulatorInspNoticeCO {
|
|||
@ApiModelProperty("被检机构id")
|
||||
private String orgId;
|
||||
|
||||
@ApiModelProperty("评价机构名称")
|
||||
private String orgName;
|
||||
|
||||
@ApiModelProperty("告知编号")
|
||||
private String noticeNo;
|
||||
|
||||
|
|
@ -23,15 +26,18 @@ public class RegulatorInspNoticeCO {
|
|||
@ApiModelProperty(value = "检查类型名称:项目过程检查/资质保持检查/专项检查", example = "项目过程检查")
|
||||
private String inspTypeName;
|
||||
|
||||
@ApiModelProperty(value = "来源方式编码:1年度计划 2专项安排 3其他", example = "1")
|
||||
@ApiModelProperty(value = "来源方式编码:1年度计划 2专项安排 3其他 4风险预警", example = "4")
|
||||
private Integer sourceTypeCode;
|
||||
|
||||
@ApiModelProperty(value = "来源方式名称:年度计划/专项安排/其他", example = "年度计划")
|
||||
@ApiModelProperty(value = "来源方式名称:年度计划/专项安排/其他/风险预警", example = "风险预警")
|
||||
private String sourceTypeName;
|
||||
|
||||
@ApiModelProperty("来源业务id")
|
||||
private String sourceRefId;
|
||||
|
||||
@ApiModelProperty("来源预警/业务编号")
|
||||
private String sourceRefNo;
|
||||
|
||||
@ApiModelProperty("关联项目id")
|
||||
private String projectId;
|
||||
|
||||
|
|
@ -44,25 +50,31 @@ public class RegulatorInspNoticeCO {
|
|||
@ApiModelProperty("告知内容")
|
||||
private String noticeContent;
|
||||
|
||||
@ApiModelProperty(value = "状态编码:1已下发 2已确认 3已反馈 4已办结", example = "1")
|
||||
@ApiModelProperty("告知附件URL,逗号分隔")
|
||||
private String noticeUrls;
|
||||
|
||||
@ApiModelProperty(value = "状态编码:0待下发 1已下发 2已确认 3已反馈 4已办结", example = "1")
|
||||
private Integer statusCode;
|
||||
|
||||
@ApiModelProperty(value = "状态名称:已下发/已确认/已反馈/已办结", example = "已下发")
|
||||
@ApiModelProperty(value = "状态名称:待下发/已下发/已确认/已反馈/已办结(原型「已完成」=已办结)", example = "已下发")
|
||||
private String statusName;
|
||||
|
||||
@ApiModelProperty(value = "机构是否确认:1是 2否", example = "2")
|
||||
private Integer confirmFlag;
|
||||
|
||||
@ApiModelProperty(value = "材料反馈:1已提交 2未提交(status>=3 为已提交)", example = "2")
|
||||
private Integer feedbackFlag;
|
||||
|
||||
@ApiModelProperty("确认时间")
|
||||
private LocalDateTime confirmTime;
|
||||
|
||||
@ApiModelProperty("下发时间")
|
||||
private LocalDateTime sendTime;
|
||||
|
||||
@ApiModelProperty(value = "检查结果编码:1合格 2不合格 3限期整改", example = "1")
|
||||
@ApiModelProperty(value = "检查结果编码:1未发现问题/合格 2责令整改/不合格 3转入风险预警/限期整改", example = "1")
|
||||
private Integer resultCode;
|
||||
|
||||
@ApiModelProperty(value = "检查结果名称:合格/不合格/限期整改", example = "合格")
|
||||
@ApiModelProperty(value = "检查结果名称", example = "未发现问题")
|
||||
private String resultName;
|
||||
|
||||
@ApiModelProperty("结果说明")
|
||||
|
|
@ -76,4 +88,7 @@ public class RegulatorInspNoticeCO {
|
|||
|
||||
@ApiModelProperty("结果登记时间")
|
||||
private LocalDateTime resultTime;
|
||||
|
||||
@ApiModelProperty("监管备注")
|
||||
private String remarks;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package org.qinan.safetyeval.client.co.report;
|
|||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Data
|
||||
|
|
@ -14,12 +15,18 @@ public class EvalReportLibraryCO {
|
|||
@ApiModelProperty("机构id")
|
||||
private String orgId;
|
||||
|
||||
@ApiModelProperty("报送机构名称")
|
||||
private String orgName;
|
||||
|
||||
@ApiModelProperty("项目id")
|
||||
private String projectId;
|
||||
|
||||
@ApiModelProperty("客户id")
|
||||
private String customerId;
|
||||
|
||||
@ApiModelProperty("被评价单位名称")
|
||||
private String evaluatedUnitName;
|
||||
|
||||
@ApiModelProperty("报告编号")
|
||||
private String reportNo;
|
||||
|
||||
|
|
@ -35,6 +42,12 @@ public class EvalReportLibraryCO {
|
|||
@ApiModelProperty("评价类型名称")
|
||||
private String evalTypeName;
|
||||
|
||||
@ApiModelProperty("所属行业编码")
|
||||
private String industryCode;
|
||||
|
||||
@ApiModelProperty("所属行业名称")
|
||||
private String industryName;
|
||||
|
||||
@ApiModelProperty("业务范围")
|
||||
private String businessScope;
|
||||
|
||||
|
|
@ -44,18 +57,40 @@ public class EvalReportLibraryCO {
|
|||
@ApiModelProperty("文件名")
|
||||
private String fileName;
|
||||
|
||||
@ApiModelProperty("是否公开")
|
||||
@ApiModelProperty("是否公开:1是2否")
|
||||
private Integer publicFlag;
|
||||
|
||||
@ApiModelProperty("资料是否完整")
|
||||
@ApiModelProperty("资料是否完整:1是2否")
|
||||
private Integer completeFlag;
|
||||
|
||||
@ApiModelProperty("报告状态编码")
|
||||
@ApiModelProperty("是否已报送监管:1是2否")
|
||||
private Integer submitFlag;
|
||||
|
||||
@ApiModelProperty("报告状态编码:1已入库2抽查中3待整改4已复核")
|
||||
private Integer reportStatusCode;
|
||||
|
||||
@ApiModelProperty("报告状态名称")
|
||||
private String reportStatusName;
|
||||
|
||||
@ApiModelProperty(value = "列表展示用报送状态:未报送/已报送/抽查中/整改中/已复核",
|
||||
example = "已报送")
|
||||
private String displayStatusName;
|
||||
|
||||
@ApiModelProperty("入库时间")
|
||||
private LocalDateTime archiveTime;
|
||||
|
||||
@ApiModelProperty("报告签发日期")
|
||||
private LocalDate issueDate;
|
||||
|
||||
@ApiModelProperty("报告页数")
|
||||
private Integer pageCount;
|
||||
|
||||
@ApiModelProperty("保密属性编码")
|
||||
private String secretLevelCode;
|
||||
|
||||
@ApiModelProperty("保密属性名称")
|
||||
private String secretLevelName;
|
||||
|
||||
@ApiModelProperty("备注")
|
||||
private String remarks;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
package org.qinan.safetyeval.client.co.report;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 机构端报告库页顶栏汇总
|
||||
*/
|
||||
@Data
|
||||
public class InstitutionEvalReportSummaryCO {
|
||||
|
||||
@ApiModelProperty("报告总数")
|
||||
private Long totalCount;
|
||||
|
||||
@ApiModelProperty("近三年报告数")
|
||||
private Long recentThreeYearCount;
|
||||
|
||||
@ApiModelProperty("已报送监管数")
|
||||
private Long submittedCount;
|
||||
|
||||
@ApiModelProperty("待完善分类数(资料不完整)")
|
||||
private Long incompleteCount;
|
||||
|
||||
@ApiModelProperty("监管抽查中数量")
|
||||
private Long spotcheckingCount;
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package org.qinan.safetyeval.client.co.report;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 监管端安评报告数据库页顶栏汇总
|
||||
*/
|
||||
@Data
|
||||
public class RegulatorEvalReportSummaryCO {
|
||||
|
||||
@ApiModelProperty("近三年报告数(已报送)")
|
||||
private Long recentThreeYearCount;
|
||||
|
||||
@ApiModelProperty("本年度报告数(已报送)")
|
||||
private Long currentYearCount;
|
||||
|
||||
@ApiModelProperty("已报送报告总数")
|
||||
private Long submittedTotalCount;
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
package org.qinan.safetyeval.client.dto.institution;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.time.LocalDate;
|
||||
|
||||
/**
|
||||
* 机构端上传历史报告(对齐原型「上传历史报告」)
|
||||
*/
|
||||
@Data
|
||||
public class InstitutionEvalReportAddCmd {
|
||||
|
||||
@NotBlank(message = "报告编号不能为空")
|
||||
@ApiModelProperty(value = "报告编号", required = true, example = "CQAP-XZ-2026-001")
|
||||
private String reportNo;
|
||||
|
||||
@NotBlank(message = "报告名称不能为空")
|
||||
@ApiModelProperty(value = "报告名称", required = true)
|
||||
private String reportName;
|
||||
|
||||
@ApiModelProperty("报告年度")
|
||||
private Integer reportYear;
|
||||
|
||||
@ApiModelProperty(value = "评价类型编码:PRE/ACCEPT/STATUS", example = "PRE")
|
||||
private String evalTypeCode;
|
||||
|
||||
@ApiModelProperty(value = "评价类型名称", example = "安全预评价")
|
||||
private String evalTypeName;
|
||||
|
||||
@ApiModelProperty(value = "所属行业编码", example = "HAZCHEM")
|
||||
private String industryCode;
|
||||
|
||||
@ApiModelProperty(value = "所属行业名称", example = "危险化学品")
|
||||
private String industryName;
|
||||
|
||||
@NotBlank(message = "被评价单位不能为空")
|
||||
@ApiModelProperty(value = "被评价单位名称", required = true)
|
||||
private String evaluatedUnitName;
|
||||
|
||||
@ApiModelProperty("客户id(可选)")
|
||||
private Long customerId;
|
||||
|
||||
@NotNull(message = "报告签发日期不能为空")
|
||||
@ApiModelProperty(value = "报告签发日期", required = true, example = "2026-07-16")
|
||||
private LocalDate issueDate;
|
||||
|
||||
@ApiModelProperty("报告页数")
|
||||
private Integer pageCount;
|
||||
|
||||
@NotBlank(message = "文件地址不能为空")
|
||||
@ApiModelProperty(value = "文件地址(先走文件上传拿 URL)", required = true)
|
||||
private String fileUrl;
|
||||
|
||||
@ApiModelProperty("文件名")
|
||||
private String fileName;
|
||||
|
||||
@ApiModelProperty(value = "保密属性编码:NORMAL/TRADE_SECRET/PRIVACY/CLASSIFIED", example = "NORMAL")
|
||||
private String secretLevelCode;
|
||||
|
||||
@ApiModelProperty(value = "保密属性名称", example = "普通")
|
||||
private String secretLevelName;
|
||||
|
||||
@ApiModelProperty("备注")
|
||||
private String remarks;
|
||||
|
||||
@ApiModelProperty(value = "是否同步报送监管端:true=已报送(status已入库);false=仅存机构库", example = "false")
|
||||
private Boolean submitToRegulator;
|
||||
}
|
||||
|
|
@ -9,12 +9,22 @@ import org.qinan.safetyeval.client.dto.BasePageQuery;
|
|||
@EqualsAndHashCode(callSuper = true)
|
||||
public class InstitutionEvalReportPageQuery extends BasePageQuery {
|
||||
|
||||
@ApiModelProperty("关键词(报告名称/编号)")
|
||||
private String keyword;
|
||||
|
||||
@ApiModelProperty("报告年度")
|
||||
private Integer reportYear;
|
||||
|
||||
@ApiModelProperty(value = "评价类型编码:PRE安全预评价 ACCEPT安全验收评价 STATUS安全现状评价", example = "PRE")
|
||||
private String evalTypeCode;
|
||||
|
||||
@ApiModelProperty(value = "所属行业编码", example = "HAZCHEM")
|
||||
private String industryCode;
|
||||
|
||||
@ApiModelProperty(value = "报告状态编码:1已入库 2抽查中 3待整改 4已复核", example = "1")
|
||||
private Integer reportStatusCode;
|
||||
|
||||
@ApiModelProperty(value = "报送展示状态:UN_SUBMITTED未报送 SUBMITTED已报送 SPOTCHECKING抽查中 RECTIFYING整改中 REVIEWED已复核",
|
||||
example = "SUBMITTED")
|
||||
private String displayStatus;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
package org.qinan.safetyeval.client.dto.institution;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
/**
|
||||
* 机构端将未报送报告报送监管
|
||||
*/
|
||||
@Data
|
||||
public class InstitutionEvalReportSubmitCmd {
|
||||
|
||||
@NotNull(message = "报告ID不能为空")
|
||||
@ApiModelProperty(value = "报告ID", required = true)
|
||||
private Long id;
|
||||
}
|
||||
|
|
@ -1,7 +1,9 @@
|
|||
package org.qinan.safetyeval.client.dto.institution;
|
||||
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import org.qinan.safetyeval.client.jackson.SnowflakeIdStringDeserializer;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
|
|
@ -9,6 +11,7 @@ import javax.validation.constraints.NotNull;
|
|||
public class InstitutionInspNoticeConfirmCmd {
|
||||
|
||||
@NotNull
|
||||
@ApiModelProperty(value = "告知id", required = true)
|
||||
private Long id;
|
||||
@JsonDeserialize(using = SnowflakeIdStringDeserializer.class)
|
||||
@ApiModelProperty(value = "告知id(字符串,避免雪花ID精度丢失)", required = true)
|
||||
private String id;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
package org.qinan.safetyeval.client.dto.institution;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 机构端导出消息清单 CSV。优先 ids;否则按筛选。始终限定本机构。
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class InstitutionInspNoticeExportCmd extends InstitutionInspNoticePageQuery {
|
||||
|
||||
@ApiModelProperty("勾选的告知ID(字符串,避免雪花精度丢失)")
|
||||
private List<String> ids;
|
||||
|
||||
@ApiModelProperty(value = "导出范围:SELECTED / FILTERED / ALL", example = "FILTERED")
|
||||
private String scope;
|
||||
}
|
||||
|
|
@ -1,7 +1,9 @@
|
|||
package org.qinan.safetyeval.client.dto.institution;
|
||||
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import org.qinan.safetyeval.client.jackson.SnowflakeIdStringDeserializer;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
|
|
@ -10,8 +12,9 @@ import java.util.List;
|
|||
public class InstitutionInspNoticeFeedbackCmd {
|
||||
|
||||
@NotNull
|
||||
@ApiModelProperty(value = "告知id", required = true)
|
||||
private Long id;
|
||||
@JsonDeserialize(using = SnowflakeIdStringDeserializer.class)
|
||||
@ApiModelProperty(value = "告知id(字符串,避免雪花ID精度丢失)", required = true)
|
||||
private String id;
|
||||
|
||||
@ApiModelProperty("随反馈一并上传的材料(可选)")
|
||||
private List<InstitutionInspNoticeMaterialUploadCmd> materials;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
package org.qinan.safetyeval.client.dto.institution;
|
||||
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import org.qinan.safetyeval.client.jackson.SnowflakeIdStringDeserializer;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
|
@ -10,8 +12,9 @@ import javax.validation.constraints.NotNull;
|
|||
public class InstitutionInspNoticeMaterialUploadCmd {
|
||||
|
||||
@NotNull
|
||||
@ApiModelProperty(value = "材料id", required = true)
|
||||
private Long materialId;
|
||||
@JsonDeserialize(using = SnowflakeIdStringDeserializer.class)
|
||||
@ApiModelProperty(value = "材料id(字符串,避免雪花ID精度丢失)", required = true)
|
||||
private String materialId;
|
||||
|
||||
@NotBlank
|
||||
@ApiModelProperty(value = "文件URL", required = true)
|
||||
|
|
|
|||
|
|
@ -9,12 +9,27 @@ import org.qinan.safetyeval.client.dto.BasePageQuery;
|
|||
@EqualsAndHashCode(callSuper = true)
|
||||
public class InstitutionInspNoticePageQuery extends BasePageQuery {
|
||||
|
||||
@ApiModelProperty("告知编号")
|
||||
@ApiModelProperty("告知编号(模糊)")
|
||||
private String noticeNo;
|
||||
|
||||
@ApiModelProperty("关键词:告知编号/来源预警编号/告知内容")
|
||||
private String keyword;
|
||||
|
||||
@ApiModelProperty(value = "状态编码:1已下发 2已确认 3已反馈 4已办结", example = "1")
|
||||
private Integer statusCode;
|
||||
|
||||
@ApiModelProperty(value = "检查类型编码:PROJECT_PROCESS项目过程检查 QUAL_KEEP资质保持检查 SPECIAL专项检查", example = "PROJECT_PROCESS")
|
||||
@ApiModelProperty(value = "检查类型编码:PROJECT_PROCESS/QUAL_KEEP/SPECIAL", example = "PROJECT_PROCESS")
|
||||
private String inspTypeCode;
|
||||
|
||||
@ApiModelProperty(value = "来源方式编码:1年度计划 2专项安排 3其他 4风险预警", example = "4")
|
||||
private Integer sourceTypeCode;
|
||||
|
||||
@ApiModelProperty("来源预警编号(模糊)")
|
||||
private String sourceRefNo;
|
||||
|
||||
@ApiModelProperty(value = "机构确认:1已确认 2未确认", example = "2")
|
||||
private Integer confirmFlag;
|
||||
|
||||
@ApiModelProperty(value = "材料反馈:1已提交 2未提交", example = "2")
|
||||
private Integer feedbackFlag;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,11 @@ import lombok.Data;
|
|||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.time.LocalDate;
|
||||
|
||||
/**
|
||||
* 监管端补录历史报告(字段与机构端上传对齐,强制已报送)
|
||||
*/
|
||||
@Data
|
||||
public class RegulatorEvalReportAddCmd {
|
||||
|
||||
|
|
@ -13,25 +17,43 @@ public class RegulatorEvalReportAddCmd {
|
|||
@ApiModelProperty(value = "机构id", required = true)
|
||||
private Long orgId;
|
||||
|
||||
@ApiModelProperty("项目id(可空)")
|
||||
@ApiModelProperty("项目id(可空,历史补录)")
|
||||
private Long projectId;
|
||||
|
||||
@NotBlank(message = "报告名称不能为空")
|
||||
@ApiModelProperty(value = "报告名称", required = true)
|
||||
private String reportName;
|
||||
|
||||
@ApiModelProperty("报告编号")
|
||||
@ApiModelProperty(value = "报告编号", example = "CQAP-2026-0715")
|
||||
private String reportNo;
|
||||
|
||||
@ApiModelProperty("报告年度")
|
||||
private Integer reportYear;
|
||||
|
||||
@ApiModelProperty(value = "评价类型编码:PRE安全预评价 ACCEPT安全验收评价 STATUS安全现状评价", example = "PRE")
|
||||
@ApiModelProperty(value = "评价类型编码:PRE/ACCEPT/STATUS", example = "PRE")
|
||||
private String evalTypeCode;
|
||||
|
||||
@ApiModelProperty(value = "评价类型名称:安全预评价/安全验收评价/安全现状评价", example = "安全预评价")
|
||||
@ApiModelProperty(value = "评价类型名称", example = "安全预评价")
|
||||
private String evalTypeName;
|
||||
|
||||
@ApiModelProperty(value = "所属行业编码", example = "HAZCHEM")
|
||||
private String industryCode;
|
||||
|
||||
@ApiModelProperty(value = "所属行业名称", example = "危险化学品")
|
||||
private String industryName;
|
||||
|
||||
@ApiModelProperty("被评价单位名称")
|
||||
private String evaluatedUnitName;
|
||||
|
||||
@ApiModelProperty("客户id(可选)")
|
||||
private Long customerId;
|
||||
|
||||
@ApiModelProperty("报告签发日期")
|
||||
private LocalDate issueDate;
|
||||
|
||||
@ApiModelProperty("报告页数")
|
||||
private Integer pageCount;
|
||||
|
||||
@ApiModelProperty("业务范围")
|
||||
private String businessScope;
|
||||
|
||||
|
|
@ -41,4 +63,13 @@ public class RegulatorEvalReportAddCmd {
|
|||
|
||||
@ApiModelProperty("文件名")
|
||||
private String fileName;
|
||||
|
||||
@ApiModelProperty(value = "保密属性编码", example = "NORMAL")
|
||||
private String secretLevelCode;
|
||||
|
||||
@ApiModelProperty(value = "保密属性名称", example = "普通")
|
||||
private String secretLevelName;
|
||||
|
||||
@ApiModelProperty("备注")
|
||||
private String remarks;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
package org.qinan.safetyeval.client.dto.regulator;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 监管端批量下载报告文件(打包 ZIP)
|
||||
*/
|
||||
@Data
|
||||
public class RegulatorEvalReportBatchDownloadCmd {
|
||||
|
||||
@NotEmpty(message = "请选择需要下载的报告")
|
||||
@ApiModelProperty(value = "报告ID列表", required = true)
|
||||
private List<Long> ids;
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package org.qinan.safetyeval.client.dto.regulator;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 监管端导出报告目录(CSV,Excel 可直接打开)。
|
||||
* <p>
|
||||
* 优先按 {@code ids} 导出勾选项;未传 ids 时按筛选条件导出(默认仅已报送)。
|
||||
* </p>
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class RegulatorEvalReportExportCmd extends RegulatorEvalReportPageQuery {
|
||||
|
||||
@ApiModelProperty("勾选的报告ID;非空时忽略分页,按勾选导出")
|
||||
private List<Long> ids;
|
||||
|
||||
@ApiModelProperty(value = "导出范围:SELECTED=勾选 FILTERED=当前筛选 ALL=全部已报送;未传时:有ids则SELECTED否则FILTERED",
|
||||
example = "FILTERED")
|
||||
private String scope;
|
||||
}
|
||||
|
|
@ -9,15 +9,33 @@ import org.qinan.safetyeval.client.dto.BasePageQuery;
|
|||
@EqualsAndHashCode(callSuper = true)
|
||||
public class RegulatorEvalReportPageQuery extends BasePageQuery {
|
||||
|
||||
@ApiModelProperty("机构id")
|
||||
@ApiModelProperty("机构id(精确)")
|
||||
private Long orgId;
|
||||
|
||||
@ApiModelProperty("报送机构名称(模糊)")
|
||||
private String orgName;
|
||||
|
||||
@ApiModelProperty("关键词(报告名称/编号)")
|
||||
private String keyword;
|
||||
|
||||
@ApiModelProperty("报告年度")
|
||||
private Integer reportYear;
|
||||
|
||||
@ApiModelProperty(value = "评价类型编码:PRE安全预评价 ACCEPT安全验收评价 STATUS安全现状评价", example = "PRE")
|
||||
private String evalTypeCode;
|
||||
|
||||
@ApiModelProperty(value = "所属行业编码", example = "HAZCHEM")
|
||||
private String industryCode;
|
||||
|
||||
@ApiModelProperty(value = "报告状态编码:1已入库 2抽查中 3待整改 4已复核", example = "1")
|
||||
private Integer reportStatusCode;
|
||||
|
||||
@ApiModelProperty(value = "报送时间起 yyyy-MM-dd", example = "2026-01-01")
|
||||
private String archiveTimeStart;
|
||||
|
||||
@ApiModelProperty(value = "报送时间止 yyyy-MM-dd", example = "2026-12-31")
|
||||
private String archiveTimeEnd;
|
||||
|
||||
@ApiModelProperty(value = "是否已报送:默认仅查已报送(1)。传 0/null 以外值可放宽", example = "1")
|
||||
private Integer submitFlag;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
package org.qinan.safetyeval.client.dto.regulator;
|
||||
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import org.qinan.safetyeval.client.jackson.SnowflakeIdStringDeserializer;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.List;
|
||||
|
|
@ -10,13 +12,14 @@ import java.util.List;
|
|||
public class RegulatorInspNoticeCloseCmd {
|
||||
|
||||
@NotNull
|
||||
@ApiModelProperty(value = "告知id", required = true)
|
||||
private Long id;
|
||||
@JsonDeserialize(using = SnowflakeIdStringDeserializer.class)
|
||||
@ApiModelProperty(value = "告知id(字符串,避免雪花ID精度丢失)", required = true)
|
||||
private String id;
|
||||
|
||||
@ApiModelProperty(value = "检查结果编码:1合格 2不合格 3限期整改", example = "1")
|
||||
@ApiModelProperty(value = "检查结果编码:1未发现问题/合格 2责令整改/不合格 3转入风险预警/限期整改", example = "1")
|
||||
private Integer resultCode;
|
||||
|
||||
@ApiModelProperty(value = "检查结果名称:合格/不合格/限期整改", example = "合格")
|
||||
@ApiModelProperty(value = "检查结果名称(原型:未发现问题/责令整改/转入风险预警)", example = "未发现问题")
|
||||
private String resultName;
|
||||
|
||||
@ApiModelProperty("结果说明")
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
package org.qinan.safetyeval.client.dto.regulator;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 导出台账 CSV。优先 ids;否则按筛选条件。
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class RegulatorInspNoticeExportCmd extends RegulatorInspNoticePageQuery {
|
||||
|
||||
@ApiModelProperty("勾选的告知ID;非空时按勾选导出")
|
||||
private List<Long> ids;
|
||||
|
||||
@ApiModelProperty(value = "导出范围:SELECTED / FILTERED / ALL;未传时有ids则SELECTED否则FILTERED", example = "FILTERED")
|
||||
private String scope;
|
||||
}
|
||||
|
|
@ -1,18 +1,23 @@
|
|||
package org.qinan.safetyeval.client.dto.regulator;
|
||||
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import org.qinan.safetyeval.client.jackson.SnowflakeIdStringDeserializer;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class RegulatorInspNoticeIssueCmd {
|
||||
|
||||
@NotNull
|
||||
@ApiModelProperty(value = "被检机构id", required = true)
|
||||
private Long orgId;
|
||||
@JsonDeserialize(using = SnowflakeIdStringDeserializer.class)
|
||||
@ApiModelProperty("草稿告知id;传入则将待下发草稿正式下发(字符串)")
|
||||
private String id;
|
||||
|
||||
@JsonDeserialize(using = SnowflakeIdStringDeserializer.class)
|
||||
@ApiModelProperty(value = "被检机构id(org_info.id,新建下发时必填,字符串避免精度丢失)")
|
||||
private String orgId;
|
||||
|
||||
@ApiModelProperty(value = "检查类型编码:PROJECT_PROCESS项目过程检查 QUAL_KEEP资质保持检查 SPECIAL专项检查", example = "PROJECT_PROCESS")
|
||||
private String inspTypeCode;
|
||||
|
|
@ -20,15 +25,18 @@ public class RegulatorInspNoticeIssueCmd {
|
|||
@ApiModelProperty(value = "检查类型名称:项目过程检查/资质保持检查/专项检查", example = "项目过程检查")
|
||||
private String inspTypeName;
|
||||
|
||||
@ApiModelProperty(value = "来源方式编码:1年度计划 2专项安排 3其他", example = "1")
|
||||
@ApiModelProperty(value = "来源方式编码:1年度计划 2专项安排 3其他 4风险预警", example = "4")
|
||||
private Integer sourceTypeCode;
|
||||
|
||||
@ApiModelProperty(value = "来源方式名称:年度计划/专项安排/其他", example = "年度计划")
|
||||
@ApiModelProperty(value = "来源方式名称:年度计划/专项安排/其他/风险预警", example = "风险预警")
|
||||
private String sourceTypeName;
|
||||
|
||||
@ApiModelProperty("来源业务id")
|
||||
private Long sourceRefId;
|
||||
|
||||
@ApiModelProperty("来源预警/业务编号")
|
||||
private String sourceRefNo;
|
||||
|
||||
@ApiModelProperty("关联项目id")
|
||||
private Long projectId;
|
||||
|
||||
|
|
@ -41,6 +49,12 @@ public class RegulatorInspNoticeIssueCmd {
|
|||
@ApiModelProperty("告知内容")
|
||||
private String noticeContent;
|
||||
|
||||
@ApiModelProperty("告知附件URL列表")
|
||||
private List<String> noticeUrls;
|
||||
|
||||
@ApiModelProperty("监管备注")
|
||||
private String remarks;
|
||||
|
||||
@ApiModelProperty("预置材料名称列表")
|
||||
private List<String> materialNames;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,15 +12,39 @@ public class RegulatorInspNoticePageQuery extends BasePageQuery {
|
|||
@ApiModelProperty("被检机构id")
|
||||
private Long orgId;
|
||||
|
||||
@ApiModelProperty("告知编号")
|
||||
@ApiModelProperty("评价机构名称(模糊)")
|
||||
private String orgName;
|
||||
|
||||
@ApiModelProperty("告知编号(模糊)")
|
||||
private String noticeNo;
|
||||
|
||||
@ApiModelProperty(value = "状态编码:1已下发 2已确认 3已反馈 4已办结", example = "1")
|
||||
@ApiModelProperty("关键词:告知编号/来源预警编号/告知内容/负责人")
|
||||
private String keyword;
|
||||
|
||||
@ApiModelProperty(value = "状态编码:0待下发 1已下发 2已确认 3已反馈 4已办结(原型「已完成」传4)", example = "1")
|
||||
private Integer statusCode;
|
||||
|
||||
@ApiModelProperty(value = "检查类型编码:PROJECT_PROCESS项目过程检查 QUAL_KEEP资质保持检查 SPECIAL专项检查", example = "PROJECT_PROCESS")
|
||||
@ApiModelProperty(value = "检查类型编码:PROJECT_PROCESS/QUAL_KEEP/SPECIAL", example = "PROJECT_PROCESS")
|
||||
private String inspTypeCode;
|
||||
|
||||
@ApiModelProperty("检查组长")
|
||||
@ApiModelProperty("检查组长(模糊)")
|
||||
private String leaderName;
|
||||
|
||||
@ApiModelProperty(value = "来源方式编码:1年度计划 2专项安排 3其他 4风险预警", example = "4")
|
||||
private Integer sourceTypeCode;
|
||||
|
||||
@ApiModelProperty("来源预警编号(模糊)")
|
||||
private String sourceRefNo;
|
||||
|
||||
@ApiModelProperty(value = "计划检查时间起(yyyy-MM-dd)", example = "2026-07-01")
|
||||
private String planInspTimeStart;
|
||||
|
||||
@ApiModelProperty(value = "计划检查时间止(yyyy-MM-dd)", example = "2026-07-31")
|
||||
private String planInspTimeEnd;
|
||||
|
||||
@ApiModelProperty(value = "机构确认:1已确认 2未确认", example = "2")
|
||||
private Integer confirmFlag;
|
||||
|
||||
@ApiModelProperty(value = "材料反馈:1已提交 2未提交", example = "2")
|
||||
private Integer feedbackFlag;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
package org.qinan.safetyeval.client.dto.regulator;
|
||||
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import org.qinan.safetyeval.client.jackson.SnowflakeIdStringDeserializer;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
@Data
|
||||
public class RegulatorInspNoticeRemarkCmd {
|
||||
|
||||
@NotNull
|
||||
@JsonDeserialize(using = SnowflakeIdStringDeserializer.class)
|
||||
@ApiModelProperty(value = "告知id(字符串,避免雪花ID精度丢失)", required = true)
|
||||
private String id;
|
||||
|
||||
@ApiModelProperty("监管备注")
|
||||
private String remarks;
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
package org.qinan.safetyeval.client.dto.regulator;
|
||||
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import org.qinan.safetyeval.client.jackson.SnowflakeIdStringDeserializer;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 暂存/编辑待下发告知(status=0)。
|
||||
*/
|
||||
@Data
|
||||
public class RegulatorInspNoticeSaveCmd {
|
||||
|
||||
@JsonDeserialize(using = SnowflakeIdStringDeserializer.class)
|
||||
@ApiModelProperty("主键;空=新建草稿,非空=编辑待下发草稿(字符串)")
|
||||
private String id;
|
||||
|
||||
@NotNull
|
||||
@JsonDeserialize(using = SnowflakeIdStringDeserializer.class)
|
||||
@ApiModelProperty(value = "被检机构id(org_info.id,字符串避免精度丢失)", required = true)
|
||||
private String orgId;
|
||||
|
||||
@ApiModelProperty(value = "检查类型编码:PROJECT_PROCESS/QUAL_KEEP/SPECIAL", example = "PROJECT_PROCESS")
|
||||
private String inspTypeCode;
|
||||
|
||||
@ApiModelProperty(value = "检查类型名称", example = "项目过程检查")
|
||||
private String inspTypeName;
|
||||
|
||||
@ApiModelProperty(value = "来源方式编码:1年度计划 2专项安排 3其他 4风险预警", example = "1")
|
||||
private Integer sourceTypeCode;
|
||||
|
||||
@ApiModelProperty(value = "来源方式名称", example = "年度计划")
|
||||
private String sourceTypeName;
|
||||
|
||||
@ApiModelProperty("来源业务id")
|
||||
private Long sourceRefId;
|
||||
|
||||
@ApiModelProperty("来源预警/业务编号")
|
||||
private String sourceRefNo;
|
||||
|
||||
@ApiModelProperty("关联项目id")
|
||||
private Long projectId;
|
||||
|
||||
@ApiModelProperty("计划检查时间")
|
||||
private LocalDateTime planInspTime;
|
||||
|
||||
@ApiModelProperty("检查组长")
|
||||
private String leaderName;
|
||||
|
||||
@ApiModelProperty("告知内容")
|
||||
private String noticeContent;
|
||||
|
||||
@ApiModelProperty("告知附件URL列表")
|
||||
private List<String> noticeUrls;
|
||||
|
||||
@ApiModelProperty("监管备注")
|
||||
private String remarks;
|
||||
|
||||
@ApiModelProperty("预置材料名称列表(仅新建草稿时生效)")
|
||||
private List<String> materialNames;
|
||||
}
|
||||
|
|
@ -1,7 +1,9 @@
|
|||
package org.qinan.safetyeval.client.dto.regulator;
|
||||
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import org.qinan.safetyeval.client.jackson.SnowflakeIdStringDeserializer;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
|
|
@ -9,6 +11,7 @@ import javax.validation.constraints.NotNull;
|
|||
public class RegulatorInspNoticeUrgeCmd {
|
||||
|
||||
@NotNull
|
||||
@ApiModelProperty(value = "告知id", required = true)
|
||||
private Long id;
|
||||
@JsonDeserialize(using = SnowflakeIdStringDeserializer.class)
|
||||
@ApiModelProperty(value = "告知id(字符串,避免雪花ID精度丢失)", required = true)
|
||||
private String id;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
package org.qinan.safetyeval.client.jackson;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.JsonToken;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* 将 JSON 中的数字或字符串 ID 反序列化为字符串,避免 Long 精度丢失。
|
||||
*/
|
||||
public class SnowflakeIdStringDeserializer extends JsonDeserializer<String> {
|
||||
|
||||
@Override
|
||||
public String deserialize(JsonParser parser, DeserializationContext ctxt) throws IOException {
|
||||
JsonToken token = parser.getCurrentToken();
|
||||
if (token == JsonToken.VALUE_STRING) {
|
||||
return parser.getText().trim();
|
||||
}
|
||||
if (token == JsonToken.VALUE_NUMBER_INT || token == JsonToken.VALUE_NUMBER_FLOAT) {
|
||||
// 用原文文本,避免 Long 精度丢失;兼容各 Jackson 版本
|
||||
return parser.getText().trim();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -11,19 +11,35 @@ public class EvalReportEntity {
|
|||
private Long orgId;
|
||||
private Long projectId;
|
||||
private Long customerId;
|
||||
/** 被评价单位名称(历史补录可无 customerId) */
|
||||
private String evaluatedUnitName;
|
||||
private String reportNo;
|
||||
private String reportName;
|
||||
private Integer reportYear;
|
||||
private String evalTypeCode;
|
||||
private String evalTypeName;
|
||||
/** 所属行业编码 */
|
||||
private String industryCode;
|
||||
/** 所属行业名称 */
|
||||
private String industryName;
|
||||
private String businessScope;
|
||||
private String fileUrl;
|
||||
private String fileName;
|
||||
private Integer publicFlag;
|
||||
private Integer completeFlag;
|
||||
/** 是否已报送监管:1是 2否 */
|
||||
private Integer submitFlag;
|
||||
private Integer reportStatusCode;
|
||||
private String reportStatusName;
|
||||
private LocalDateTime archiveTime;
|
||||
/** 报告签发日期 */
|
||||
private java.time.LocalDate issueDate;
|
||||
/** 报告页数 */
|
||||
private Integer pageCount;
|
||||
/** 保密属性编码 */
|
||||
private String secretLevelCode;
|
||||
/** 保密属性名称 */
|
||||
private String secretLevelName;
|
||||
private String deleteEnum;
|
||||
private String remarks;
|
||||
private String createName;
|
||||
|
|
|
|||
|
|
@ -15,10 +15,12 @@ public class InspNoticeEntity {
|
|||
private Integer sourceTypeCode;
|
||||
private String sourceTypeName;
|
||||
private Long sourceRefId;
|
||||
private String sourceRefNo;
|
||||
private Long projectId;
|
||||
private LocalDateTime planInspTime;
|
||||
private String leaderName;
|
||||
private String noticeContent;
|
||||
private String noticeUrls;
|
||||
private Integer statusCode;
|
||||
private String statusName;
|
||||
private Integer confirmFlag;
|
||||
|
|
@ -31,5 +33,6 @@ public class InspNoticeEntity {
|
|||
private Long resultRecorderId;
|
||||
private String resultRecorderName;
|
||||
private LocalDateTime resultTime;
|
||||
private String remarks;
|
||||
private Long tenantId;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -174,6 +174,8 @@ public enum ErrorCode {
|
|||
INSP_NOTICE_NO_GENERATE_FAILED("06-06-004", "告知编号生成失败"),
|
||||
INSP_NOTICE_MATERIAL_NOT_FOUND("06-06-005", "监督检查材料不存在"),
|
||||
INSP_NOTICE_MATERIAL_INCOMPLETE("06-06-006", "必填材料未上传完整"),
|
||||
INSP_NOTICE_EXPORT_EMPTY("06-06-007", "没有可导出的监督检查告知"),
|
||||
INSP_NOTICE_EXPORT_TOO_LARGE("06-06-008", "导出数量超过上限"),
|
||||
|
||||
// ---- 报告库与抽查(phase2 P4) ----
|
||||
EVAL_REPORT_NOT_FOUND("06-07-001", "安评报告不存在"),
|
||||
|
|
@ -183,6 +185,11 @@ public enum ErrorCode {
|
|||
EVAL_REPORT_SPOTCHECK_IN_PROGRESS("06-07-005", "该报告已有进行中的抽查"),
|
||||
EVAL_REPORT_SPOTCHECK_INVALID("06-07-006", "抽查状态不允许该操作"),
|
||||
EVAL_REPORT_RECTIFY_REQUIRE_MISSING("06-07-007", "不合格抽查须填写整改要求"),
|
||||
EVAL_REPORT_NO_DUPLICATE("06-07-008", "报告编号已存在"),
|
||||
EVAL_REPORT_ALREADY_SUBMITTED("06-07-009", "报告已报送监管,无需重复报送"),
|
||||
EVAL_REPORT_BATCH_EMPTY("06-07-010", "请选择需要操作的报告"),
|
||||
EVAL_REPORT_BATCH_TOO_LARGE("06-07-011", "批量操作数量超过上限"),
|
||||
EVAL_REPORT_FILE_MISSING("06-07-012", "所选报告均无有效文件地址,无法打包下载"),
|
||||
|
||||
// ---- 机构画像得分(phase2 P4) ----
|
||||
ORG_PROFILE_SCORE_NOT_FOUND("06-08-001", "机构画像得分不存在"),
|
||||
|
|
|
|||
|
|
@ -15,4 +15,13 @@ public interface EvalReportGateway {
|
|||
EvalReportEntity saveInternal(EvalReportEntity entity);
|
||||
|
||||
PageResult<EvalReportEntity> page(EvalReportQuery query);
|
||||
|
||||
long count(EvalReportQuery query);
|
||||
|
||||
EvalReportEntity findByOrgIdAndReportNo(Long orgId, String reportNo);
|
||||
|
||||
/**
|
||||
* 按主键批量查询(保持 ids 顺序;跳过不存在/已删)。
|
||||
*/
|
||||
java.util.List<EvalReportEntity> listByIds(java.util.List<Long> ids);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,4 +17,20 @@ public class EvalReportQuery {
|
|||
private String evalTypeCode;
|
||||
/** 报告状态编码:1已入库 2抽查中 3待整改 4已复核,示例:1 */
|
||||
private Integer reportStatusCode;
|
||||
/** 关键词:报告名称/编号 */
|
||||
private String keyword;
|
||||
/** 所属行业编码 */
|
||||
private String industryCode;
|
||||
/** 是否已报送监管:1是 2否 */
|
||||
private Integer submitFlag;
|
||||
/** 资料是否完整:1是 2否 */
|
||||
private Integer completeFlag;
|
||||
/** 近 N 年(含当年),用于汇总:report_year >= recentYearFrom */
|
||||
private Integer recentYearFrom;
|
||||
/** 报送/入库时间起(含) */
|
||||
private java.time.LocalDateTime archiveTimeFrom;
|
||||
/** 报送/入库时间止(含) */
|
||||
private java.time.LocalDateTime archiveTimeTo;
|
||||
/** 机构 id 列表(按机构名称解析后过滤) */
|
||||
private java.util.List<Long> orgIds;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,16 +2,34 @@ package org.qinan.safetyeval.domain.query;
|
|||
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class InspNoticeQuery {
|
||||
|
||||
private Long pageNum;
|
||||
private Long pageSize;
|
||||
private Long orgId;
|
||||
private List<Long> orgIds;
|
||||
private List<Long> ids;
|
||||
private String noticeNo;
|
||||
/** 状态编码:1已下发 2已确认 3已反馈 4已办结,示例:1 */
|
||||
private String keyword;
|
||||
/** 状态编码:0待下发 1已下发 2已确认 3已反馈 4已办结 */
|
||||
private Integer statusCode;
|
||||
/** 检查类型编码:PROJECT_PROCESS项目过程检查 QUAL_KEEP资质保持检查 SPECIAL专项检查,示例:PROJECT_PROCESS */
|
||||
/** 检查类型编码 */
|
||||
private String inspTypeCode;
|
||||
private String leaderName;
|
||||
/** 来源方式编码:1年度计划 2专项安排 3其他 4风险预警 */
|
||||
private Integer sourceTypeCode;
|
||||
/** 来源预警/业务编号(模糊) */
|
||||
private String sourceRefNo;
|
||||
private LocalDateTime planInspTimeFrom;
|
||||
private LocalDateTime planInspTimeTo;
|
||||
/** 机构是否确认:1是 2否 */
|
||||
private Integer confirmFlag;
|
||||
/** 材料反馈:1已提交(status>=3) 2未提交(status<3) */
|
||||
private Integer feedbackFlag;
|
||||
/** 最小状态(含),如机构端传 1 排除草稿 */
|
||||
private Integer minStatusCode;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,9 +41,69 @@ public class EvalReportDomainService {
|
|||
if (entity.getPublicFlag() == null) {
|
||||
entity.setPublicFlag(2);
|
||||
}
|
||||
if (entity.getSubmitFlag() == null) {
|
||||
entity.setSubmitFlag(1);
|
||||
}
|
||||
if (entity.getCompleteFlag() == null) {
|
||||
entity.setCompleteFlag(1);
|
||||
}
|
||||
return evalReportGateway.saveInternal(entity);
|
||||
}
|
||||
|
||||
public EvalReportEntity addForInstitution(EvalReportEntity entity) {
|
||||
assertReportNoUnique(entity.getOrgId(), entity.getReportNo(), null);
|
||||
entity.setReportStatusCode(STATUS_ARCHIVED);
|
||||
entity.setReportStatusName("已入库");
|
||||
entity.setArchiveTime(LocalDateTime.now());
|
||||
if (entity.getPublicFlag() == null) {
|
||||
entity.setPublicFlag(2);
|
||||
}
|
||||
if (entity.getSubmitFlag() == null) {
|
||||
entity.setSubmitFlag(2);
|
||||
}
|
||||
if (entity.getCompleteFlag() == null) {
|
||||
boolean incomplete = !org.springframework.util.StringUtils.hasText(entity.getIndustryCode())
|
||||
&& !org.springframework.util.StringUtils.hasText(entity.getIndustryName());
|
||||
entity.setCompleteFlag(incomplete ? 2 : 1);
|
||||
}
|
||||
return evalReportGateway.save(entity);
|
||||
}
|
||||
|
||||
public EvalReportEntity submitToRegulator(Long id) {
|
||||
EvalReportEntity existing = get(id);
|
||||
if (existing.getSubmitFlag() != null && existing.getSubmitFlag() == 1) {
|
||||
throw new BizException(ErrorCode.EVAL_REPORT_ALREADY_SUBMITTED);
|
||||
}
|
||||
EvalReportEntity update = new EvalReportEntity();
|
||||
update.setId(id);
|
||||
update.setOrgId(existing.getOrgId());
|
||||
update.setSubmitFlag(1);
|
||||
update.setReportStatusCode(STATUS_ARCHIVED);
|
||||
update.setReportStatusName("已入库");
|
||||
if (existing.getArchiveTime() == null) {
|
||||
update.setArchiveTime(LocalDateTime.now());
|
||||
}
|
||||
return evalReportGateway.modify(update);
|
||||
}
|
||||
|
||||
public void assertReportNoUnique(Long orgId, String reportNo, Long excludeId) {
|
||||
if (!org.springframework.util.StringUtils.hasText(reportNo)) {
|
||||
return;
|
||||
}
|
||||
EvalReportEntity found = evalReportGateway.findByOrgIdAndReportNo(orgId, reportNo);
|
||||
if (found != null && (excludeId == null || !excludeId.equals(found.getId()))) {
|
||||
throw new BizException(ErrorCode.EVAL_REPORT_NO_DUPLICATE);
|
||||
}
|
||||
}
|
||||
|
||||
public long count(EvalReportQuery query) {
|
||||
return evalReportGateway.count(query);
|
||||
}
|
||||
|
||||
public java.util.List<EvalReportEntity> listByIds(java.util.List<Long> ids) {
|
||||
return evalReportGateway.listByIds(ids);
|
||||
}
|
||||
|
||||
public EvalReportEntity updateStatus(Long id, int statusCode, String statusName) {
|
||||
EvalReportEntity existing = get(id);
|
||||
EvalReportEntity update = new EvalReportEntity();
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ import java.time.LocalDateTime;
|
|||
@Service
|
||||
public class InspNoticeDomainService {
|
||||
|
||||
/** 待下发(草稿) */
|
||||
public static final int STATUS_DRAFT = 0;
|
||||
public static final int STATUS_ISSUED = 1;
|
||||
public static final int STATUS_CONFIRMED = 2;
|
||||
public static final int STATUS_FEEDBACK = 3;
|
||||
|
|
@ -50,6 +52,27 @@ public class InspNoticeDomainService {
|
|||
return inspNoticeGateway.page(query);
|
||||
}
|
||||
|
||||
public InspNoticeEntity saveDraft(InspNoticeEntity entity) {
|
||||
entity.setStatusCode(STATUS_DRAFT);
|
||||
entity.setSendTime(null);
|
||||
entity.setConfirmFlag(2);
|
||||
entity.setConfirmTime(null);
|
||||
return add(entity);
|
||||
}
|
||||
|
||||
public InspNoticeEntity updateDraft(InspNoticeEntity entity) {
|
||||
InspNoticeEntity existing = get(entity.getId());
|
||||
if (existing.getStatusCode() == null || existing.getStatusCode() != STATUS_DRAFT) {
|
||||
throw new BizException(ErrorCode.INSP_NOTICE_STATUS_INVALID);
|
||||
}
|
||||
entity.setStatusCode(STATUS_DRAFT);
|
||||
entity.setSendTime(null);
|
||||
if (entity.getConfirmFlag() == null) {
|
||||
entity.setConfirmFlag(2);
|
||||
}
|
||||
return modify(entity);
|
||||
}
|
||||
|
||||
public InspNoticeEntity issue(InspNoticeEntity entity) {
|
||||
entity.setStatusCode(STATUS_ISSUED);
|
||||
entity.setSendTime(LocalDateTime.now());
|
||||
|
|
@ -57,6 +80,27 @@ public class InspNoticeDomainService {
|
|||
return add(entity);
|
||||
}
|
||||
|
||||
public InspNoticeEntity issueDraft(Long id) {
|
||||
InspNoticeEntity existing = get(id);
|
||||
if (existing.getStatusCode() == null || existing.getStatusCode() != STATUS_DRAFT) {
|
||||
throw new BizException(ErrorCode.INSP_NOTICE_STATUS_INVALID);
|
||||
}
|
||||
InspNoticeEntity update = new InspNoticeEntity();
|
||||
update.setId(id);
|
||||
update.setStatusCode(STATUS_ISSUED);
|
||||
update.setSendTime(LocalDateTime.now());
|
||||
update.setConfirmFlag(2);
|
||||
return modify(update);
|
||||
}
|
||||
|
||||
public InspNoticeEntity updateRemarks(Long id, String remarks) {
|
||||
get(id);
|
||||
InspNoticeEntity update = new InspNoticeEntity();
|
||||
update.setId(id);
|
||||
update.setRemarks(remarks);
|
||||
return modify(update);
|
||||
}
|
||||
|
||||
public InspNoticeEntity confirm(Long id) {
|
||||
InspNoticeEntity existing = get(id);
|
||||
if (existing.getStatusCode() == null || existing.getStatusCode() != STATUS_ISSUED) {
|
||||
|
|
@ -113,6 +157,9 @@ public class InspNoticeDomainService {
|
|||
return;
|
||||
}
|
||||
switch (entity.getStatusCode()) {
|
||||
case STATUS_DRAFT:
|
||||
entity.setStatusName("待下发");
|
||||
break;
|
||||
case STATUS_ISSUED:
|
||||
entity.setStatusName("已下发");
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ public class EvalReportDO {
|
|||
private Long orgId;
|
||||
private Long projectId;
|
||||
private Long customerId;
|
||||
/** 被评价单位名称(历史补录可无 customerId) */
|
||||
private String evaluatedUnitName;
|
||||
private String reportNo;
|
||||
private String reportName;
|
||||
private Integer reportYear;
|
||||
|
|
@ -19,6 +21,8 @@ public class EvalReportDO {
|
|||
private String evalTypeCode;
|
||||
/** 评价类型名称:安全预评价/安全验收评价/安全现状评价,示例:安全预评价 */
|
||||
private String evalTypeName;
|
||||
private String industryCode;
|
||||
private String industryName;
|
||||
private String businessScope;
|
||||
private String fileUrl;
|
||||
private String fileName;
|
||||
|
|
@ -26,11 +30,17 @@ public class EvalReportDO {
|
|||
private Integer publicFlag;
|
||||
/** 资料是否完整:1是 2否,示例:2 */
|
||||
private Integer completeFlag;
|
||||
/** 是否已报送监管:1是 2否 */
|
||||
private Integer submitFlag;
|
||||
/** 报告状态编码:1已入库 2抽查中 3待整改 4已复核,示例:1 */
|
||||
private Integer reportStatusCode;
|
||||
/** 报告状态名称:已入库/抽查中/待整改/已复核,示例:已入库 */
|
||||
private String reportStatusName;
|
||||
private LocalDateTime archiveTime;
|
||||
private java.time.LocalDate issueDate;
|
||||
private Integer pageCount;
|
||||
private String secretLevelCode;
|
||||
private String secretLevelName;
|
||||
private String deleteEnum;
|
||||
private String remarks;
|
||||
private String createName;
|
||||
|
|
|
|||
|
|
@ -12,30 +12,28 @@ public class InspNoticeDO {
|
|||
private Long id;
|
||||
private Long orgId;
|
||||
private String noticeNo;
|
||||
/** 检查类型编码:PROJECT_PROCESS项目过程检查 QUAL_KEEP资质保持检查 SPECIAL专项检查,示例:PROJECT_PROCESS */
|
||||
/** 检查类型编码:PROJECT_PROCESS项目过程检查 QUAL_KEEP资质保持检查 SPECIAL专项检查 */
|
||||
private String inspTypeCode;
|
||||
/** 检查类型名称:项目过程检查/资质保持检查/专项检查,示例:项目过程检查 */
|
||||
private String inspTypeName;
|
||||
/** 来源方式编码:1年度计划 2专项安排 3其他,示例:1 */
|
||||
/** 来源方式编码:1年度计划 2专项安排 3其他 4风险预警 */
|
||||
private Integer sourceTypeCode;
|
||||
/** 来源方式名称:年度计划/专项安排/其他,示例:年度计划 */
|
||||
private String sourceTypeName;
|
||||
private Long sourceRefId;
|
||||
private String sourceRefNo;
|
||||
private Long projectId;
|
||||
private LocalDateTime planInspTime;
|
||||
private String leaderName;
|
||||
private String noticeContent;
|
||||
/** 状态编码:1已下发 2已确认 3已反馈 4已办结,示例:1 */
|
||||
private String noticeUrls;
|
||||
/** 状态编码:0待下发 1已下发 2已确认 3已反馈 4已办结 */
|
||||
private Integer statusCode;
|
||||
/** 状态名称:已下发/已确认/已反馈/已办结,示例:已下发 */
|
||||
private String statusName;
|
||||
/** 机构是否确认:1是 2否,示例:2 */
|
||||
/** 机构是否确认:1是 2否 */
|
||||
private Integer confirmFlag;
|
||||
private LocalDateTime confirmTime;
|
||||
private LocalDateTime sendTime;
|
||||
/** 检查结果编码:1合格 2不合格 3限期整改,示例:1 */
|
||||
/** 检查结果编码:1未发现问题/合格 2责令整改/不合格 3转入风险预警/限期整改 */
|
||||
private Integer resultCode;
|
||||
/** 检查结果名称:合格/不合格/限期整改,示例:合格 */
|
||||
private String resultName;
|
||||
private String resultContent;
|
||||
private String resultUrls;
|
||||
|
|
|
|||
|
|
@ -71,12 +71,67 @@ public class EvalReportGatewayImpl implements EvalReportGateway {
|
|||
return PageResult.of(entities, result.getTotal(), result.getCurrent(), result.getSize());
|
||||
}
|
||||
|
||||
@Override
|
||||
public long count(EvalReportQuery query) {
|
||||
Long cnt = evalReportMapper.selectCount(buildQueryWrapper(query));
|
||||
return cnt == null ? 0L : cnt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public EvalReportEntity findByOrgIdAndReportNo(Long orgId, String reportNo) {
|
||||
if (orgId == null || !org.springframework.util.StringUtils.hasText(reportNo)) {
|
||||
return null;
|
||||
}
|
||||
LambdaQueryWrapper<EvalReportDO> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(EvalReportDO::getDeleteEnum, "false");
|
||||
wrapper.eq(EvalReportDO::getOrgId, orgId);
|
||||
wrapper.eq(EvalReportDO::getReportNo, reportNo.trim());
|
||||
wrapper.last("limit 1");
|
||||
return toEntity(evalReportMapper.selectOne(wrapper));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<EvalReportEntity> listByIds(List<Long> ids) {
|
||||
if (ids == null || ids.isEmpty()) {
|
||||
return java.util.Collections.emptyList();
|
||||
}
|
||||
List<EvalReportDO> records = evalReportMapper.selectBatchIds(ids);
|
||||
if (records == null || records.isEmpty()) {
|
||||
return java.util.Collections.emptyList();
|
||||
}
|
||||
java.util.Map<Long, EvalReportEntity> map = new java.util.HashMap<Long, EvalReportEntity>();
|
||||
for (EvalReportDO dataObject : records) {
|
||||
if (dataObject == null || !"false".equals(dataObject.getDeleteEnum())) {
|
||||
continue;
|
||||
}
|
||||
EvalReportEntity entity = toEntity(dataObject);
|
||||
if (entity != null && entity.getId() != null) {
|
||||
map.put(entity.getId(), entity);
|
||||
}
|
||||
}
|
||||
List<EvalReportEntity> ordered = new java.util.ArrayList<EvalReportEntity>();
|
||||
for (Long id : ids) {
|
||||
EvalReportEntity entity = map.get(id);
|
||||
if (entity != null) {
|
||||
ordered.add(entity);
|
||||
}
|
||||
}
|
||||
return ordered;
|
||||
}
|
||||
|
||||
private LambdaQueryWrapper<EvalReportDO> buildQueryWrapper(EvalReportQuery query) {
|
||||
LambdaQueryWrapper<EvalReportDO> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(EvalReportDO::getDeleteEnum, "false");
|
||||
if (query.getOrgId() != null) {
|
||||
wrapper.eq(EvalReportDO::getOrgId, query.getOrgId());
|
||||
}
|
||||
if (query.getOrgIds() != null) {
|
||||
if (query.getOrgIds().isEmpty()) {
|
||||
wrapper.eq(EvalReportDO::getId, -1L);
|
||||
} else {
|
||||
wrapper.in(EvalReportDO::getOrgId, query.getOrgIds());
|
||||
}
|
||||
}
|
||||
if (query.getProjectId() != null) {
|
||||
wrapper.eq(EvalReportDO::getProjectId, query.getProjectId());
|
||||
}
|
||||
|
|
@ -89,6 +144,28 @@ public class EvalReportGatewayImpl implements EvalReportGateway {
|
|||
if (query.getReportStatusCode() != null) {
|
||||
wrapper.eq(EvalReportDO::getReportStatusCode, query.getReportStatusCode());
|
||||
}
|
||||
if (org.springframework.util.StringUtils.hasText(query.getIndustryCode())) {
|
||||
wrapper.eq(EvalReportDO::getIndustryCode, query.getIndustryCode());
|
||||
}
|
||||
if (query.getSubmitFlag() != null) {
|
||||
wrapper.eq(EvalReportDO::getSubmitFlag, query.getSubmitFlag());
|
||||
}
|
||||
if (query.getCompleteFlag() != null) {
|
||||
wrapper.eq(EvalReportDO::getCompleteFlag, query.getCompleteFlag());
|
||||
}
|
||||
if (query.getRecentYearFrom() != null) {
|
||||
wrapper.ge(EvalReportDO::getReportYear, query.getRecentYearFrom());
|
||||
}
|
||||
if (query.getArchiveTimeFrom() != null) {
|
||||
wrapper.ge(EvalReportDO::getArchiveTime, query.getArchiveTimeFrom());
|
||||
}
|
||||
if (query.getArchiveTimeTo() != null) {
|
||||
wrapper.le(EvalReportDO::getArchiveTime, query.getArchiveTimeTo());
|
||||
}
|
||||
if (org.springframework.util.StringUtils.hasText(query.getKeyword())) {
|
||||
String kw = query.getKeyword().trim();
|
||||
wrapper.and(w -> w.like(EvalReportDO::getReportName, kw).or().like(EvalReportDO::getReportNo, kw));
|
||||
}
|
||||
wrapper.orderByDesc(EvalReportDO::getArchiveTime).orderByDesc(EvalReportDO::getCreateTime);
|
||||
return wrapper;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import org.qinan.safetyeval.infrastructure.mapper.InspNoticeMapper;
|
|||
import org.qinan.safetyeval.infrastructure.support.InsertFieldDefaults;
|
||||
import org.qinan.safetyeval.infrastructure.support.OrgContextResolver;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
|
@ -39,12 +40,16 @@ public class InspNoticeGatewayImpl implements InspNoticeGateway {
|
|||
@Override
|
||||
public InspNoticeEntity get(Long id) {
|
||||
InspNoticeDO dataObject = inspNoticeMapper.selectById(id);
|
||||
if (dataObject == null || !"false".equals(dataObject.getDeleteEnum())) {
|
||||
if (dataObject == null || isDeleted(dataObject.getDeleteEnum())) {
|
||||
return null;
|
||||
}
|
||||
return toEntity(dataObject);
|
||||
}
|
||||
|
||||
private boolean isDeleted(String deleteEnum) {
|
||||
return deleteEnum != null && !"false".equals(deleteEnum);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InspNoticeEntity modify(InspNoticeEntity entity) {
|
||||
InspNoticeDO existing = inspNoticeMapper.selectById(entity.getId());
|
||||
|
|
@ -76,11 +81,26 @@ public class InspNoticeGatewayImpl implements InspNoticeGateway {
|
|||
if (query.getOrgId() != null) {
|
||||
wrapper.eq(InspNoticeDO::getOrgId, query.getOrgId());
|
||||
}
|
||||
if (!CollectionUtils.isEmpty(query.getOrgIds())) {
|
||||
wrapper.in(InspNoticeDO::getOrgId, query.getOrgIds());
|
||||
}
|
||||
if (!CollectionUtils.isEmpty(query.getIds())) {
|
||||
wrapper.in(InspNoticeDO::getId, query.getIds());
|
||||
}
|
||||
if (StringUtils.hasText(query.getNoticeNo())) {
|
||||
wrapper.like(InspNoticeDO::getNoticeNo, query.getNoticeNo());
|
||||
}
|
||||
if (StringUtils.hasText(query.getKeyword())) {
|
||||
String kw = query.getKeyword().trim();
|
||||
wrapper.and(w -> w.like(InspNoticeDO::getNoticeNo, kw)
|
||||
.or().like(InspNoticeDO::getSourceRefNo, kw)
|
||||
.or().like(InspNoticeDO::getNoticeContent, kw)
|
||||
.or().like(InspNoticeDO::getLeaderName, kw));
|
||||
}
|
||||
if (query.getStatusCode() != null) {
|
||||
wrapper.eq(InspNoticeDO::getStatusCode, query.getStatusCode());
|
||||
} else if (query.getMinStatusCode() != null) {
|
||||
wrapper.ge(InspNoticeDO::getStatusCode, query.getMinStatusCode());
|
||||
}
|
||||
if (StringUtils.hasText(query.getInspTypeCode())) {
|
||||
wrapper.eq(InspNoticeDO::getInspTypeCode, query.getInspTypeCode());
|
||||
|
|
@ -88,6 +108,28 @@ public class InspNoticeGatewayImpl implements InspNoticeGateway {
|
|||
if (StringUtils.hasText(query.getLeaderName())) {
|
||||
wrapper.like(InspNoticeDO::getLeaderName, query.getLeaderName());
|
||||
}
|
||||
if (query.getSourceTypeCode() != null) {
|
||||
wrapper.eq(InspNoticeDO::getSourceTypeCode, query.getSourceTypeCode());
|
||||
}
|
||||
if (StringUtils.hasText(query.getSourceRefNo())) {
|
||||
wrapper.like(InspNoticeDO::getSourceRefNo, query.getSourceRefNo());
|
||||
}
|
||||
if (query.getPlanInspTimeFrom() != null) {
|
||||
wrapper.ge(InspNoticeDO::getPlanInspTime, query.getPlanInspTimeFrom());
|
||||
}
|
||||
if (query.getPlanInspTimeTo() != null) {
|
||||
wrapper.le(InspNoticeDO::getPlanInspTime, query.getPlanInspTimeTo());
|
||||
}
|
||||
if (query.getConfirmFlag() != null) {
|
||||
wrapper.eq(InspNoticeDO::getConfirmFlag, query.getConfirmFlag());
|
||||
}
|
||||
if (query.getFeedbackFlag() != null) {
|
||||
if (query.getFeedbackFlag() == 1) {
|
||||
wrapper.ge(InspNoticeDO::getStatusCode, 3);
|
||||
} else if (query.getFeedbackFlag() == 2) {
|
||||
wrapper.lt(InspNoticeDO::getStatusCode, 3);
|
||||
}
|
||||
}
|
||||
wrapper.orderByDesc(InspNoticeDO::getSendTime).orderByDesc(InspNoticeDO::getCreateTime);
|
||||
return wrapper;
|
||||
}
|
||||
|
|
@ -101,10 +143,12 @@ public class InspNoticeGatewayImpl implements InspNoticeGateway {
|
|||
dataObject.setSourceTypeCode(entity.getSourceTypeCode());
|
||||
dataObject.setSourceTypeName(entity.getSourceTypeName());
|
||||
dataObject.setSourceRefId(entity.getSourceRefId());
|
||||
dataObject.setSourceRefNo(entity.getSourceRefNo());
|
||||
dataObject.setProjectId(entity.getProjectId());
|
||||
dataObject.setPlanInspTime(entity.getPlanInspTime());
|
||||
dataObject.setLeaderName(entity.getLeaderName());
|
||||
dataObject.setNoticeContent(entity.getNoticeContent());
|
||||
dataObject.setNoticeUrls(entity.getNoticeUrls());
|
||||
dataObject.setStatusCode(entity.getStatusCode());
|
||||
dataObject.setStatusName(entity.getStatusName());
|
||||
dataObject.setConfirmFlag(entity.getConfirmFlag());
|
||||
|
|
@ -117,6 +161,7 @@ public class InspNoticeGatewayImpl implements InspNoticeGateway {
|
|||
dataObject.setResultRecorderId(entity.getResultRecorderId());
|
||||
dataObject.setResultRecorderName(entity.getResultRecorderName());
|
||||
dataObject.setResultTime(entity.getResultTime());
|
||||
dataObject.setRemarks(entity.getRemarks());
|
||||
dataObject.setTenantId(entity.getTenantId());
|
||||
return dataObject;
|
||||
}
|
||||
|
|
@ -134,10 +179,12 @@ public class InspNoticeGatewayImpl implements InspNoticeGateway {
|
|||
entity.setSourceTypeCode(dataObject.getSourceTypeCode());
|
||||
entity.setSourceTypeName(dataObject.getSourceTypeName());
|
||||
entity.setSourceRefId(dataObject.getSourceRefId());
|
||||
entity.setSourceRefNo(dataObject.getSourceRefNo());
|
||||
entity.setProjectId(dataObject.getProjectId());
|
||||
entity.setPlanInspTime(dataObject.getPlanInspTime());
|
||||
entity.setLeaderName(dataObject.getLeaderName());
|
||||
entity.setNoticeContent(dataObject.getNoticeContent());
|
||||
entity.setNoticeUrls(dataObject.getNoticeUrls());
|
||||
entity.setStatusCode(dataObject.getStatusCode());
|
||||
entity.setStatusName(dataObject.getStatusName());
|
||||
entity.setConfirmFlag(dataObject.getConfirmFlag());
|
||||
|
|
@ -150,6 +197,7 @@ public class InspNoticeGatewayImpl implements InspNoticeGateway {
|
|||
entity.setResultRecorderId(dataObject.getResultRecorderId());
|
||||
entity.setResultRecorderName(dataObject.getResultRecorderName());
|
||||
entity.setResultTime(dataObject.getResultTime());
|
||||
entity.setRemarks(dataObject.getRemarks());
|
||||
entity.setTenantId(dataObject.getTenantId());
|
||||
return entity;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
package org.qinan.safetyeval.infrastructure.support;
|
||||
|
||||
import org.qinan.safetyeval.domain.exception.BizException;
|
||||
import org.qinan.safetyeval.domain.exception.ErrorCode;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* 监督检查告知 ID 解析:接口层统一使用字符串,避免前端 Number 精度丢失。
|
||||
*/
|
||||
public final class InspNoticeIdSupport {
|
||||
|
||||
private InspNoticeIdSupport() {
|
||||
}
|
||||
|
||||
public static Long parseNoticeId(String id) {
|
||||
if (!StringUtils.hasText(id)) {
|
||||
throw new BizException(ErrorCode.REGULATOR_EVAL_PARAM_INVALID, "告知id不能为空");
|
||||
}
|
||||
try {
|
||||
return Long.parseLong(id.trim());
|
||||
} catch (NumberFormatException ex) {
|
||||
throw new BizException(ErrorCode.REGULATOR_EVAL_PARAM_INVALID, "告知id格式无效");
|
||||
}
|
||||
}
|
||||
|
||||
public static Long parseOrgId(String orgId) {
|
||||
if (!StringUtils.hasText(orgId)) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return Long.parseLong(orgId.trim());
|
||||
} catch (NumberFormatException ex) {
|
||||
throw new BizException(ErrorCode.REGULATOR_EVAL_PARAM_INVALID, "被检机构id格式无效");
|
||||
}
|
||||
}
|
||||
|
||||
public static Long parseMaterialId(String materialId) {
|
||||
if (!StringUtils.hasText(materialId)) {
|
||||
throw new BizException(ErrorCode.REGULATOR_EVAL_PARAM_INVALID, "材料id不能为空");
|
||||
}
|
||||
try {
|
||||
return Long.parseLong(materialId.trim());
|
||||
} catch (NumberFormatException ex) {
|
||||
throw new BizException(ErrorCode.REGULATOR_EVAL_PARAM_INVALID, "材料id格式无效");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,11 @@
|
|||
package org.qinan.safetyeval.infrastructure.support;
|
||||
|
||||
import org.qinan.safetyeval.domain.entity.OrgInfoEntity;
|
||||
import org.qinan.safetyeval.domain.exception.BizException;
|
||||
import org.qinan.safetyeval.domain.exception.ErrorCode;
|
||||
import org.qinan.safetyeval.domain.gateway.OrgInfoGateway;
|
||||
import org.qinan.safetyeval.infrastructure.adapter.ThreadLocalUserInfoAdapter;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
|
|
@ -11,11 +14,23 @@ import org.springframework.stereotype.Component;
|
|||
@Component
|
||||
public class InstitutionOrgSupport {
|
||||
|
||||
@Autowired(required = false)
|
||||
private OrgInfoGateway orgInfoGateway;
|
||||
|
||||
public Long resolveCurrentOrgId() {
|
||||
Long orgId = ThreadLocalUserInfoAdapter.getOrgId();
|
||||
if (orgId == null) {
|
||||
orgId = ThreadLocalUserInfoAdapter.get();
|
||||
}
|
||||
if (orgId == null && orgInfoGateway != null) {
|
||||
OrgInfoEntity orgInfo = orgInfoGateway.getInfo();
|
||||
if (orgInfo != null) {
|
||||
orgId = orgInfo.getId();
|
||||
}
|
||||
}
|
||||
if (orgId == null) {
|
||||
throw new BizException(ErrorCode.ORG_INFO_NOT_FOUND);
|
||||
}
|
||||
return orgId;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue