风险预警中心

dev_1.0.1
huwei 2026-07-16 11:13:53 +08:00
parent 9ff16b1104
commit e44c711e93
18 changed files with 218 additions and 2756 deletions

View File

@ -29,7 +29,7 @@ paths:
tags:
- 监管端-风险预警中心
summary: 页面概览
description: 加载统计卡片与消息处理动作说明
description: 加载统计卡片(资质预警、项目预警、待机构反馈、今日闭环)
operationId: regulatorRiskOverview
responses:
'200':
@ -43,89 +43,18 @@ paths:
code: "0"
data:
stats:
- label: 未处理预警
value: "5"
hint: 需监管人员处置
- label: 紧急消息
- label: 资质预警
value: "6"
hint: 条件保持、人员比例、属地材料
- label: 项目预警
value: "7"
hint: 进度、人员、告知、勘查、质控
- label: 待机构反馈
value: "4"
hint: 证书过期、社保异常
- label: 重要提醒
value: "2"
hint: 证书临期、变更停滞
- label: 今日已处置
value: "2"
hint: 含发函、确认、转办
processGuide: 查看来源 → 核查材料/字段 → 发函或转办 → 设置处理结论 → 标记闭环。所有按钮均写入处置记录,用于监管留痕。
/safetyEval/regulator/risk-center/high-priority-alerts:
get:
tags:
- 监管端-风险预警中心
summary: 高优先级消息列表
description: 加载页面中部「高优先级消息」区块,默认返回紧急且未处理的前 2 条
operationId: regulatorRiskHighPriorityAlerts
parameters:
- $ref: '#/components/parameters/levelParam'
- name: warningType
in: query
description: 预警类型
schema:
type: string
enum:
- 证书过期
- 证书临期
- 社保异常
- 人员离职
- 信息变更
- name: sourceModule
in: query
description: 来源模块
schema:
type: string
example: 评价师信息管理
- name: keyword
in: query
description: 标题/预警编号/预警内容关键字
schema:
type: string
- name: onlyUntreated
in: query
description: 仅未处理(未处理/待确认/处理中)
schema:
type: boolean
default: true
- name: limit
in: query
description: 返回条数上限
schema:
type: integer
default: 2
minimum: 1
responses:
'200':
description: 成功
content:
application/json:
schema:
$ref: '#/components/schemas/SingleResponseRegulatorRiskPriorityAlertList'
example:
success: true
code: "0"
data:
- title: 评价师证书已过期
description: 来源:评价师信息管理.证书有效期;触发:有效期至 2026-06-01。
messageId: W-2026-008
level: danger
warningType: 证书过期
sourceModule: 评价师信息管理
status: 未处理
- title: 社保多处缴纳
description: 来源:资质保持监控.社保缴纳单位;触发:同一人员两家机构。
messageId: W-2026-007
level: danger
warningType: 社保异常
sourceModule: 资质保持监控
status: 未处理
hint: 整改说明或证明材料
- label: 今日闭环
value: "5"
hint: 监管复核已完成
/safetyEval/regulator/risk-center/page:
get:
@ -133,35 +62,52 @@ paths:
- 监管端-风险预警中心
summary: 分页查询预警消息
description: |
消息列表分页查询,支持搜索栏与筛选条件。
风险预警消息列表分页查询,支持关键词与各下拉条件筛选。
下拉选项:
- 预警大类:`资质预警` / `项目预警`
- 预警子类:资质条件保持异常 / 人员比例异常 / 属地材料待核验 / 项目启动超期 / 关键节点超期 / 项目人员异常 / 从业告知异常 / 现场勘查异常 / 过程控制/归档异常
- 处理阶段:`未处理` / `已发机构` / `待复核` / `已闭环`
operationId: regulatorRiskPage
parameters:
- name: keyword
in: query
description: 机构/人员/项目/预警编号
description: 关键词(机构/项目/人员/预警编号
schema:
type: string
- name: warningType
- name: type
in: query
description: 预警
description: 预警
schema:
type: string
enum:
- 证书过期
- 证书临期
- 社保异常
- 人员离职
- 信息变更
- $ref: '#/components/parameters/levelParam'
- name: processStatus
- 资质预警
- 项目预警
- name: subtype
in: query
description: 处理状态
description: 预警子类
schema:
type: string
enum:
- 资质条件保持异常
- 人员比例异常
- 属地材料待核验
- 项目启动超期
- 关键节点超期
- 项目人员异常
- 从业告知异常
- 现场勘查异常
- 过程控制/归档异常
- name: stage
in: query
description: 处理阶段
schema:
type: string
enum:
- 未处理
- 处理中
- 已处理
- 已发机构
- 待复核
- 已闭环
- $ref: '#/components/parameters/currentParam'
- $ref: '#/components/parameters/sizeParam'
responses:
@ -174,96 +120,32 @@ paths:
example:
success: true
code: "0"
total: 4
total: 7
data:
- id: W-2026-008
warningType: 证书过期
level: 紧急
levelName: 紧急
sourceModule: 评价师信息管理
- id: W-QUAL-2026-012
category: 资质预警
subtype: 资质条件保持异常
riskObject: 重庆渝安风险评估中心
sourceFields:
- 人员姓名
- 证书类型
- 有效期至
content: 张建国一级安全评价师证书已过期,机构未上传延续材料。
status: 未处理
sourceModuleKey: evaluator
/safetyEval/regulator/risk-center/handle:
post:
tags:
- 监管端-风险预警中心
summary: 处置预警
description: |
处理弹窗提交、列表行内「闭环」「发函」「提醒」等操作。
status 自动推断规则(未传 status 时):
- handleType 含「闭环」→ 已闭环
- handleType 含「发函」→ 已发函
- handleType 含「提醒」→ 已提醒
- handleType 含「转办」「转备案」→ 处理中
- 其他 → 已处置
operationId: regulatorRiskHandle
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/RegulatorRiskHandleCmd'
example:
id: W-2026-008
handleType: 标记闭环
deadline: "2026-07-18"
opinion: 请核查证书延续材料
status: 已闭环
responses:
'200':
description: 成功
content:
application/json:
schema:
$ref: '#/components/schemas/SingleResponseRegulatorRiskMessageCO'
example:
success: true
code: "0"
data:
id: W-2026-008
warningType: 证书过期
level: 紧急
levelName: 紧急
sourceModule: 评价师信息管理
sourceFields:
- 人员姓名
- 证书类型
- 有效期至
content: 张建国一级安全评价师证书已过期,机构未上传延续材料。
status: 已闭环
sourceModuleKey: evaluator
'404':
description: 预警不存在
content:
application/json:
schema:
$ref: '#/components/schemas/SingleResponseError'
example:
success: false
code: "404"
message: 预警不存在
errMessage: 预警不存在
- 财务材料.固定资产
- 场所核验.建筑面积
- 人员库.专职人数
content: 固定资产、场所面积、档案室面积和专职人员数量不满足保持条件。
stage: 未处理
orgStatus: 未发送
- id: W-PROJ-2026-021
category: 项目预警
subtype: 项目启动超期
riskObject: 华安化工年度安全现状评价
sourceFields:
- 客户信息.评价到期日
- 项目库.新建时间
content: 评价周期已到期 14 天,系统内尚未建立新一轮评价项目。
stage: 未处理
orgStatus: 未发送
components:
parameters:
levelParam:
name: level
in: query
description: 预警等级
schema:
type: string
enum:
- 紧急
- 重要
- 一般
default: 紧急
currentParam:
name: current
in: query
@ -315,40 +197,6 @@ components:
data:
$ref: '#/components/schemas/RegulatorRiskOverviewCO'
SingleResponseRegulatorRiskPriorityAlertList:
type: object
properties:
success:
type: boolean
example: true
code:
type: string
example: "0"
message:
type: string
errMessage:
type: string
data:
type: array
items:
$ref: '#/components/schemas/RegulatorRiskPriorityAlertCO'
SingleResponseRegulatorRiskMessageCO:
type: object
properties:
success:
type: boolean
example: true
code:
type: string
example: "0"
message:
type: string
errMessage:
type: string
data:
$ref: '#/components/schemas/RegulatorRiskMessageCO'
PageResponseRegulatorRiskMessageCO:
type: object
properties:
@ -366,7 +214,7 @@ components:
type: integer
format: int64
description: 总条数
example: 8
example: 7
data:
type: array
items:
@ -382,9 +230,6 @@ components:
description: 统计卡片
items:
$ref: '#/components/schemas/StatCardCO'
processGuide:
type: string
description: 消息处理动作说明
StatCardCO:
type: object
@ -392,86 +237,47 @@ components:
label:
type: string
description: 标签
example: 未处理预警
example: 资质预警
value:
type: string
description: 数值
example: "5"
example: "6"
hint:
type: string
description: 提示
example: 需监管人员处置
RegulatorRiskPriorityAlertCO:
type: object
description: 高优先级预警消息
properties:
title:
type: string
description: 标题
example: 评价师证书已过期
description:
type: string
description: 描述(含来源与触发规则)
messageId:
type: string
description: 关联预警编号
example: W-2026-008
level:
type: string
description: 展示级别
enum:
- danger
- warning
- info
example: danger
warningType:
type: string
description: 预警类型
example: 证书过期
sourceModule:
type: string
description: 来源模块
example: 评价师信息管理
status:
type: string
description: 当前状态
example: 未处理
example: 条件保持、人员比例、属地材料
RegulatorRiskMessageCO:
type: object
description: 预警消息
description: 风险预警消息
properties:
id:
type: string
description: 预警编号
example: W-2026-008
warningType:
example: W-QUAL-2026-012
category:
type: string
description: 预警
description: 预警大类
enum:
- 证书过期
- 证书临期
- 社保异常
- 人员离职
- 信息变更
level:
- 资质预警
- 项目预警
subtype:
type: string
description: 预警等级
description: 预警子类
enum:
- 紧急
- 重要
- 一般
levelName:
- 资质条件保持异常
- 人员比例异常
- 属地材料待核验
- 项目启动超期
- 关键节点超期
- 项目人员异常
- 从业告知异常
- 现场勘查异常
- 过程控制/归档异常
riskObject:
type: string
description: 等级名称
enum:
- 紧急
- 重要
- 一般
sourceModule:
type: string
description: 来源模块
description: 风险对象
example: 重庆渝安风险评估中心
sourceFields:
type: array
description: 来源字段
@ -479,52 +285,22 @@ components:
type: string
content:
type: string
description: 预警内容
status:
description: 触发内容
stage:
type: string
description: 状态
description: 处理阶段
enum:
- 未处理
- 处理中
- 确认
- 已发机构
- 复核
- 已闭环
- 已发函
- 已提醒
- 已处置
sourceModuleKey:
orgStatus:
type: string
description: 来源模块跳转标识
description: 机构端状态
enum:
- evaluator
- qual-monitor
- qual-change
- institution-account
RegulatorRiskHandleCmd:
type: object
description: 预警处置请求
required:
- id
- handleType
properties:
id:
type: string
description: 预警编号
example: W-2026-008
handleType:
type: string
description: 处置方式
example: 标记闭环
deadline:
type: string
format: date
description: 办理期限 yyyy-MM-dd
example: "2026-07-18"
opinion:
type: string
description: 处置意见
example: 请核查证书延续材料
status:
type: string
description: 处置后状态(不传则根据 handleType 自动推断)
example: 已闭环
- 未发送
- 机构未读
- 已提交材料
- 处理中
- 已提交说明
- 整改完成

View File

@ -2,7 +2,7 @@
> 仅覆盖原型页 **风险预警中心**Mock 数据内置于 `RegulatorRiskCenterController`,无数据库依赖。
> 统一前缀:`/safetyEval/regulator/risk-center`
> 接口数量:**4 个**
> 接口数量:**2 个**`GET /overview`、`GET /page`
> **OpenAPI 导入文件**[监管端-风险预警中心.openapi.yaml](./openapi/监管端-风险预警中心.openapi.yaml)(可直接导入 Apifox
---
@ -11,10 +11,8 @@
| 页面区域 | 接口 | 说明 |
|----------|------|------|
| 顶部 4 个统计卡片 + 处理动作说明 | `GET /overview` | 页面首屏统计区 |
| 高优先级消息区块 | `GET /high-priority-alerts` | 支持等级/类型/来源等筛选 |
| search-bar + 筛选 + 消息列表 | `GET /page` | 分页 + 筛选 |
| 处理 / 发函 / 闭环 / 提醒 / 审核 | `POST /handle` | 更新预警状态 |
| 顶部 4 个统计卡片 | `GET /overview` | 页面首屏统计区 |
| 搜索栏(关键词/预警大类/预警子类/处理阶段)+ 消息列表 | `GET /page` | 分页 + 筛选 |
---
@ -29,7 +27,7 @@
{ "success": true, "code": "0", "data": {} }
// PageResponse
{ "success": true, "code": "0", "data": [], "total": 8 }
{ "success": true, "code": "0", "data": [], "total": 7 }
```
### 分页参数
@ -47,36 +45,22 @@
| 字段 | 类型 | 说明 |
|------|------|------|
| stats | List\<StatCardCO\> | 统计卡片 |
| processGuide | String | 消息处理动作说明文案 |
| stats | List\<StatCardCO\> | 统计卡片4 个) |
**StatCardCO**`label` / `value` / `hint`
### RegulatorRiskPriorityAlertCO — 高优先级消息
| 字段 | 类型 | 说明 |
|------|------|------|
| title | String | 标题 |
| description | String | 描述(含来源与触发规则) |
| messageId | String | 关联预警编号 |
| level | String | danger / warning / info |
| warningType | String | 预警类型 |
| sourceModule | String | 来源模块 |
| status | String | 当前状态 |
### RegulatorRiskMessageCO — 预警消息
| 字段 | 类型 | 说明 |
|------|------|------|
| id | String | 预警编号,如 W-2026-008 |
| warningType | String | 证书过期 / 证书临期 / 社保异常 / 人员离职 / 信息变更 |
| level | String | 紧急 / 重要 / 一般 |
| levelName | String | 紧急 / 重要 / 一般 |
| sourceModule | String | 来源模块名称 |
| id | String | 预警编号,如 W-QUAL-2026-012 |
| category | String | 预警大类:资质预警 / 项目预警 |
| subtype | String | 预警子类(见下方 9 项枚举) |
| riskObject | String | 风险对象(机构或项目) |
| sourceFields | List\<String\> | 来源字段标签 |
| content | String | 预警内容 |
| status | String | 未处理 / 处理中 / 待确认 / 已闭环 / 已发函 / 已提醒 / 已处置 |
| sourceModuleKey | String | 来源跳转模块标识evaluator、qual-monitor、qual-change 等) |
| content | String | 触发内容 |
| stage | String | 处理阶段:未处理 / 已发机构 / 待复核 / 已闭环 |
| orgStatus | String | 机构端状态:未发送 / 机构未读 / 已提交材料 / 处理中 / 已提交说明 / 整改完成 |
---
@ -84,7 +68,7 @@
### 4.1 GET `/overview` — 页面概览
**用途**:加载统计卡片、处理流程说明
**用途**:加载统计卡片。
**响应示例**
@ -94,93 +78,38 @@
"code": "0",
"data": {
"stats": [
{ "label": "未处理预警", "value": "5", "hint": "需监管人员处置" },
{ "label": "紧急消息", "value": "4", "hint": "证书过期、社保异常" },
{ "label": "重要提醒", "value": "2", "hint": "证书临期、变更停滞" },
{ "label": "今日已处置", "value": "2", "hint": "含发函、确认、转办" }
],
"processGuide": "查看来源 → 核查材料/字段 → 发函或转办 → 设置处理结论 → 标记闭环。所有按钮均写入处置记录,用于监管留痕。"
{ "label": "资质预警", "value": "6", "hint": "条件保持、人员比例、属地材料" },
{ "label": "项目预警", "value": "7", "hint": "进度、人员、告知、勘查、质控" },
{ "label": "待机构反馈", "value": "4", "hint": "整改说明或证明材料" },
{ "label": "今日闭环", "value": "5", "hint": "监管复核已完成" }
]
}
}
```
> 统计数值由 Mock 消息列表动态计算,处置后再次请求会变化
> 统计数值取自原型页展示值
---
### 4.2 GET `/high-priority-alerts` — 高优先级消息
### 4.2 GET `/page` — 分页查询消息列表
**用途**:加载页面中部「高优先级消息」区块,默认展示紧急且未处理的前 2 条。
**查询参数**
| 参数 | 必填 | 默认 | 说明 |
|------|------|------|------|
| level | 否 | 紧急 | 预警等级:紧急 / 重要 / 一般 |
| warningType | 否 | — | 证书过期、证书临期、社保异常、人员离职、信息变更 |
| sourceModule | 否 | — | 来源模块,如 评价师信息管理 |
| keyword | 否 | — | 标题/预警编号/预警内容关键字 |
| onlyUntreated | 否 | true | 仅未处理(未处理/待确认/处理中) |
| limit | 否 | 2 | 返回条数上限 |
**请求示例**
```
GET /safetyEval/regulator/risk-center/high-priority-alerts
GET /safetyEval/regulator/risk-center/high-priority-alerts?level=紧急&onlyUntreated=true&limit=2
GET /safetyEval/regulator/risk-center/high-priority-alerts?level=重要&limit=5
```
**响应示例**
```json
{
"success": true,
"code": "0",
"data": [
{
"title": "评价师证书已过期",
"description": "来源:评价师信息管理.证书有效期;触发:有效期至 2026-06-01。",
"messageId": "W-2026-008",
"level": "danger",
"warningType": "证书过期",
"sourceModule": "评价师信息管理",
"status": "未处理"
},
{
"title": "社保多处缴纳",
"description": "来源:资质保持监控.社保缴纳单位;触发:同一人员两家机构。",
"messageId": "W-2026-007",
"level": "danger",
"warningType": "社保异常",
"sourceModule": "资质保持监控",
"status": "未处理"
}
]
}
```
---
### 4.3 GET `/page` — 分页查询消息列表
**查询参数**
**查询参数**(与前端下拉选项完全一致):
| 参数 | 必填 | 说明 |
|------|------|------|
| keyword | 否 | 机构/人员/项目/预警编号 |
| warningType | 否 | 证书过期、证书临期、社保异常、人员离职、信息变更 |
| level | 否 | 紧急、重要、一般 |
| processStatus | 否 | 未处理、处理中、已处理 |
| keyword | 否 | 关键词:机构/项目/人员/预警编号 |
| type | 否 | 预警大类:资质预警、项目预警 |
| subtype | 否 | 预警子类:资质条件保持异常、人员比例异常、属地材料待核验、项目启动超期、关键节点超期、项目人员异常、从业告知异常、现场勘查异常、过程控制/归档异常 |
| stage | 否 | 处理阶段:未处理、已发机构、待复核、已闭环 |
| current | 否 | 当前页 |
| size | 否 | 每页条数 |
**请求示例**
```
GET /safetyEval/regulator/risk-center/page?level=紧急&current=1&size=10
GET /safetyEval/regulator/risk-center/page?keyword=张建国&warningType=证书过期
GET /safetyEval/regulator/risk-center/page?processStatus=未处理&current=1&size=10
GET /safetyEval/regulator/risk-center/page?type=资质预警&current=1&size=10
GET /safetyEval/regulator/risk-center/page?keyword=渝安&subtype=资质条件保持异常
GET /safetyEval/regulator/risk-center/page?stage=未处理&current=1&size=10
```
**响应示例**
@ -189,108 +118,55 @@ GET /safetyEval/regulator/risk-center/page?processStatus=未处理&current=1&siz
{
"success": true,
"code": "0",
"total": 4,
"total": 7,
"data": [
{
"id": "W-2026-008",
"warningType": "证书过期",
"level": "紧急",
"levelName": "紧急",
"sourceModule": "评价师信息管理",
"sourceFields": ["人员姓名", "证书类型", "有效期至"],
"content": "张建国一级安全评价师证书已过期,机构未上传延续材料。",
"status": "未处理",
"sourceModuleKey": "evaluator"
"id": "W-QUAL-2026-012",
"category": "资质预警",
"subtype": "资质条件保持异常",
"riskObject": "重庆渝安风险评估中心",
"sourceFields": ["财务材料.固定资产", "场所核验.建筑面积", "人员库.专职人数"],
"content": "固定资产、场所面积、档案室面积和专职人员数量不满足保持条件。",
"stage": "未处理",
"orgStatus": "未发送"
}
]
}
```
---
**Mock 数据清单**7 条,参考前端原型):
### 4.4 POST `/handle` — 处置预警
**用途**:处理弹窗提交、列表行内「闭环」「发函」「提醒」等操作。
**请求体**
```json
{
"id": "W-2026-008",
"handleType": "标记闭环",
"deadline": "2026-07-18",
"opinion": "请核查证书延续材料",
"status": "已闭环"
}
```
| 字段 | 必填 | 说明 |
|------|------|------|
| id | 是 | 预警编号 |
| handleType | 是 | 发函核查 / 转备案审核 / 要求整改 / 标记闭环 / 已发函 / 已提醒 等 |
| deadline | 否 | 办理期限 |
| opinion | 否 | 处置意见 |
| status | 否 | 不传时根据 handleType 自动推断 |
**status 自动推断规则**
| handleType 含 | 默认 status |
|---------------|-------------|
| 闭环 | 已闭环 |
| 发函 | 已发函 |
| 提醒 | 已提醒 |
| 转办 / 转备案 | 处理中 |
| 其他 | 已处置 |
**响应**:返回更新后的 `RegulatorRiskMessageCO`
| 预警编号 | 预警大类 | 预警子类 | 风险对象 | 处理阶段 | 机构端状态 |
|----------|----------|----------|----------|----------|------------|
| W-QUAL-2026-012 | 资质预警 | 资质条件保持异常 | 重庆渝安风险评估中心 | 未处理 | 未发送 |
| W-QUAL-2026-011 | 资质预警 | 人员比例异常 | 重庆恒安安全评价有限公司 | 已发机构 | 机构未读 |
| W-QUAL-2026-013 | 资质预警 | 属地材料待核验 | 北京中安评价中心重庆分公司 | 待复核 | 已提交材料 |
| W-PROJ-2026-021 | 项目预警 | 项目启动超期 | 华安化工年度安全现状评价 | 未处理 | 未发送 |
| W-PROJ-2026-018 | 项目预警 | 关键节点超期 | 安环检测年度安全现状评价 | 已发机构 | 处理中 |
| W-PROJ-2026-015 | 项目预警 | 项目人员异常 | 鼎信建设安全验收评价 | 待复核 | 已提交说明 |
| W-PROJ-2026-009 | 项目预警 | 现场勘查异常 | 华安化工园区安全预评价 | 已闭环 | 整改完成 |
---
## 5. 前端对接建议
```javascript
const BASE = '/safetyEval/regulator/risk-center';
// 1. 页面初始化 - 统计区
const overview = await fetch(`${BASE}/overview`).then(r => r.json());
// 2. 高优先级消息默认紧急未处理前2条
const alerts = await fetch(`${BASE}/high-priority-alerts`).then(r => r.json());
// 3. Tab 切换 / 搜索
const list = await fetch(`${BASE}/page?level=紧急&current=1&size=10`).then(r => r.json());
// 4. 处置
await fetch(`${BASE}/handle`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ id: 'W-2026-008', handleType: '标记闭环', status: '已闭环' })
});
```
**来源跳转**:使用 `sourceModuleKey` 切换监管端左侧菜单模块(与原型 `openRegSource()` 一致)。
---
## 6. 代码位置
## 5. 代码位置
| 类型 | 路径 |
|------|------|
| Controller含 Mock | `safety-eval-adapter/.../web/regulator/RegulatorRiskCenterController.java` |
| 响应模型 | `safety-eval-client/.../co/regulator/RegulatorRiskOverviewCO.java` |
| | `safety-eval-client/.../co/regulator/RegulatorRiskPriorityAlertCO.java` |
| | `safety-eval-client/.../co/regulator/RegulatorRiskMessageCO.java` |
| 入参模型 | `safety-eval-client/.../dto/regulator/RegulatorRiskPriorityAlertQuery.java` |
| | `safety-eval-client/.../dto/regulator/RegulatorRiskMessagePageQuery.java` |
| | `safety-eval-client/.../dto/regulator/RegulatorRiskHandleCmd.java` |
| 入参模型 | `safety-eval-client/.../dto/regulator/RegulatorRiskMessagePageQuery.java` |
| 枚举 | `safety-eval-client/.../enums/regulator/RegulatorRiskCategoryEnum.java` |
| | `safety-eval-client/.../enums/regulator/RegulatorRiskSubtypeEnum.java` |
| | `safety-eval-client/.../enums/regulator/RegulatorRiskStageEnum.java` |
---
## 7. 后续真实数据对接
## 6. 后续真实数据对接
保留上述 4 个接口契约不变,将 Controller 内 Mock 逻辑替换为领域服务调用即可,前端无需改动。
保留上述 2 个接口契约不变,将 Controller 内 Mock 逻辑替换为领域服务调用即可,前端无需改动。
| 日期 | 说明 |
|------|------|
| 2026-07-14 | 初版:风险预警中心 3 接口 + Controller 内 Mock |
| 2026-07-14 | 拆分 highPriorityAlerts 为独立接口 `/high-priority-alerts` |
| 2026-07-14 | 初版:风险预警中心接口 + Controller 内 Mock |
| 2026-07-16 | 参考前端原型重构:仅保留 overview/page查询条件与下拉选项、Mock 数据与前端完全一致 |

View File

@ -4,15 +4,9 @@ import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.qinan.safetyeval.client.co.regulator.RegulatorRiskMessageCO;
import org.qinan.safetyeval.client.co.regulator.RegulatorRiskOverviewCO;
import org.qinan.safetyeval.client.co.regulator.RegulatorRiskPriorityAlertCO;
import org.qinan.safetyeval.client.dto.PageResponse;
import org.qinan.safetyeval.client.dto.SingleResponse;
import org.qinan.safetyeval.client.dto.regulator.RegulatorRiskHandleCmd;
import org.qinan.safetyeval.client.dto.regulator.RegulatorRiskMessagePageQuery;
import org.qinan.safetyeval.client.dto.regulator.RegulatorRiskPriorityAlertQuery;
import org.qinan.safetyeval.client.enums.regulator.RegulatorRiskLevelEnum;
import org.qinan.safetyeval.client.enums.regulator.RegulatorRiskProcessStatusEnum;
import org.qinan.safetyeval.client.enums.regulator.RegulatorRiskWarningTypeEnum;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@ -29,57 +23,42 @@ import java.util.stream.Collectors;
@RequestMapping("/safetyEval/regulator/risk-center")
public class RegulatorRiskCenterController {
private static final String PROCESS_GUIDE = "查看来源 → 核查材料/字段 → 发函或转办 → 设置处理结论 → 标记闭环。所有按钮均写入处置记录,用于监管留痕。";
private final List<RegulatorRiskMessageCO> messages = new ArrayList<>();
@PostConstruct
public void initMockData() {
messages.clear();
messages.add(message("W-2026-008", "证书过期", "紧急", "评价师信息管理",
Arrays.asList("人员姓名", "证书类型", "有效期至"),
"张建国一级安全评价师证书已过期,机构未上传延续材料。", "未处理", "evaluator"));
messages.add(message("W-2026-007", "社保异常", "紧急", "资质保持监控",
Arrays.asList("人员姓名", "所在机构", "社保缴纳单位"),
"王丽萍在恒安安全评价和渝安风险评估同时缴纳社保。", "未处理", "qual-monitor"));
messages.add(message("W-2026-006", "证书临期", "重要", "资质保持监控",
Arrays.asList("证书有效期", "预警阈值"),
"陈华安全评价师二级证书将于 2026-08-01 到期,距到期不足 30 天。", "处理中", "evaluator"));
messages.add(message("W-2026-005", "信息变更", "一般", "备案变更管理",
Arrays.asList("注册地址", "变更材料"),
"恒安安全评价注册地址变更材料超过 5 个工作日未确认。", "待确认", "qual-change"));
messages.add(message("W-2026-004", "人员离职", "重要", "评价师信息管理",
Arrays.asList("人员姓名", "离职日期"),
"某安全评价师已离职但仍在机构备案名单中。", "未处理", "evaluator"));
messages.add(message("W-2026-003", "人员离职", "一般", "评价师信息管理",
Arrays.asList("人员姓名", "离职日期"),
"某安全评价师已提交离职申请,资质系统未更新。", "待确认", "evaluator"));
messages.add(message("W-2026-002", "证书过期", "紧急", "评价师信息管理",
Arrays.asList("人员姓名", "证书类型", "有效期至"),
"李明华注册安全工程师证书已过期。", "已闭环", "evaluator"));
messages.add(message("W-2026-001", "社保异常", "紧急", "资质保持监控",
Arrays.asList("人员姓名", "社保缴纳单位"),
"赵磊社保缴纳单位与备案机构不一致。", "已发函", "qual-monitor"));
messages.add(message("W-QUAL-2026-012", "资质预警", "资质条件保持异常", "重庆渝安风险评估中心",
Arrays.asList("财务材料.固定资产", "场所核验.建筑面积", "人员库.专职人数"),
"固定资产、场所面积、档案室面积和专职人员数量不满足保持条件。", "未处理", "未发送"));
messages.add(message("W-QUAL-2026-011", "资质预警", "人员比例异常", "重庆恒安安全评价有限公司",
Arrays.asList("人员库.职称等级", "人员库.注册安全工程师"),
"高级职称比例 26%,合计比例 59%,低于资质保持条件。", "已发机构", "机构未读"));
messages.add(message("W-QUAL-2026-013", "资质预警", "属地材料待核验", "北京中安评价中心重庆分公司",
Arrays.asList("本市社保.缴纳人数", "场所核验.租赁合同"),
"机构已提交本地场所和人员说明,等待监管复核。", "待复核", "已提交材料"));
messages.add(message("W-PROJ-2026-021", "项目预警", "项目启动超期", "华安化工年度安全现状评价",
Arrays.asList("客户信息.评价到期日", "项目库.新建时间"),
"评价周期已到期 14 天,系统内尚未建立新一轮评价项目。", "未处理", "未发送"));
messages.add(message("W-PROJ-2026-018", "项目预警", "关键节点超期", "安环检测年度安全现状评价",
Arrays.asList("项目计划.节点期限", "流程记录.当前节点"),
"项目停留在过程控制环节 12 天,已超过计划完成时间。", "已发机构", "处理中"));
messages.add(message("W-PROJ-2026-015", "项目预警", "项目人员异常", "鼎信建设安全验收评价",
Arrays.asList("项目组.项目负责人", "人员库.在职状态"),
"项目负责人已提交离职申请,项目尚未完成负责人变更。", "待复核", "已提交说明"));
messages.add(message("W-PROJ-2026-009", "项目预警", "现场勘查异常", "华安化工园区安全预评价",
Arrays.asList("现场勘查.签到签退", "项目组.参与人员"),
"现场勘查仅有签到记录,无签退记录和现场照片。", "已闭环", "整改完成"));
}
@ApiOperation("页面概览(统计卡片 + 处理动作说明")
@ApiOperation("页面概览(统计卡片)")
@GetMapping("/overview")
public SingleResponse<RegulatorRiskOverviewCO> overview() {
RegulatorRiskOverviewCO co = new RegulatorRiskOverviewCO();
co.setStats(buildStats());
co.setProcessGuide(PROCESS_GUIDE);
return SingleResponse.success(co);
}
@ApiOperation("高优先级消息列表")
@GetMapping("/high-priority-alerts")
public SingleResponse<List<RegulatorRiskPriorityAlertCO>> highPriorityAlerts(RegulatorRiskPriorityAlertQuery query) {
if (query == null) {
query = new RegulatorRiskPriorityAlertQuery();
}
return SingleResponse.success(buildHighPriorityAlerts(query));
}
@ApiOperation("分页查询预警消息")
@GetMapping("/page")
public PageResponse<RegulatorRiskMessageCO> page(@Validated RegulatorRiskMessagePageQuery query) {
@ -99,157 +78,36 @@ public class RegulatorRiskCenterController {
return PageResponse.of(page, (long) filtered.size());
}
@ApiOperation("处置预警(处理/发函/闭环/提醒等)")
@PostMapping("/handle")
public SingleResponse<RegulatorRiskMessageCO> handle(@Validated @RequestBody RegulatorRiskHandleCmd cmd) {
Optional<RegulatorRiskMessageCO> optional = messages.stream()
.filter(m -> m.getId().equals(cmd.getId()))
.findFirst();
if (!optional.isPresent()) {
return SingleResponse.error("404", "预警不存在");
}
RegulatorRiskMessageCO message = optional.get();
message.setStatus(resolveStatus(cmd));
return SingleResponse.success(message);
}
private List<RegulatorRiskOverviewCO.StatCardCO> buildStats() {
long untreated = messages.stream().filter(m -> isUntreated(m.getStatus())).count();
long urgent = messages.stream().filter(m -> "紧急".equals(m.getLevel())).count();
long important = messages.stream().filter(m -> "重要".equals(m.getLevel())).count();
long handledToday = messages.stream().filter(m -> isHandledToday(m.getStatus())).count();
return Arrays.asList(
stat("未处理预警", String.valueOf(untreated), "需监管人员处置"),
stat("紧急消息", String.valueOf(urgent), "证书过期、社保异常"),
stat("重要提醒", String.valueOf(important), "证书临期、变更停滞"),
stat("今日已处置", String.valueOf(handledToday), "含发函、确认、转办")
stat("资质预警", "6", "条件保持、人员比例、属地材料"),
stat("项目预警", "7", "进度、人员、告知、勘查、质控"),
stat("待机构反馈", "4", "整改说明或证明材料"),
stat("今日闭环", "5", "监管复核已完成")
);
}
private List<RegulatorRiskPriorityAlertCO> buildHighPriorityAlerts(RegulatorRiskPriorityAlertQuery query) {
Map<String, String[]> titles = new HashMap<>();
titles.put("W-2026-008", new String[]{"评价师证书已过期", "来源:评价师信息管理.证书有效期;触发:有效期至 2026-06-01。"});
titles.put("W-2026-007", new String[]{"社保多处缴纳", "来源:资质保持监控.社保缴纳单位;触发:同一人员两家机构。"});
int limit = query.getLimit() == null || query.getLimit() < 1 ? 2 : query.getLimit();
return messages.stream()
.filter(m -> matchPriorityQuery(query, m))
.limit(limit)
.map(m -> toPriorityAlert(m, titles))
.collect(Collectors.toList());
}
private boolean matchPriorityQuery(RegulatorRiskPriorityAlertQuery query, RegulatorRiskMessageCO item) {
if (StringUtils.hasText(query.getLevel()) && !query.getLevel().equals(item.getLevel())) {
return false;
}
if (StringUtils.hasText(query.getWarningType()) && !query.getWarningType().equals(item.getWarningType())) {
return false;
}
if (StringUtils.hasText(query.getSourceModule()) && !query.getSourceModule().equals(item.getSourceModule())) {
return false;
}
if (Boolean.TRUE.equals(query.getOnlyUntreated()) && !isUntreated(item.getStatus())) {
return false;
}
if (StringUtils.hasText(query.getKeyword())) {
String kw = query.getKeyword().toLowerCase();
String text = (item.getId() + item.getContent() + item.getWarningType() + item.getSourceModule()).toLowerCase();
if (!text.contains(kw)) {
return false;
}
}
return true;
}
private RegulatorRiskPriorityAlertCO toPriorityAlert(RegulatorRiskMessageCO m, Map<String, String[]> titles) {
RegulatorRiskPriorityAlertCO alert = new RegulatorRiskPriorityAlertCO();
String[] preset = titles.get(m.getId());
if (preset != null) {
alert.setTitle(preset[0]);
alert.setDescription(preset[1]);
} else {
alert.setTitle(m.getWarningType());
alert.setDescription("来源:" + m.getSourceModule() + "" + m.getContent());
}
alert.setMessageId(m.getId());
alert.setLevel(alertLevel(m.getLevel()));
alert.setWarningType(m.getWarningType());
alert.setSourceModule(m.getSourceModule());
alert.setStatus(m.getStatus());
return alert;
}
private String alertLevel(String level) {
if ("紧急".equals(level)) {
return "danger";
}
if ("重要".equals(level)) {
return "warning";
}
return "info";
}
private boolean matchQuery(RegulatorRiskMessagePageQuery query, RegulatorRiskMessageCO item) {
if (StringUtils.hasText(query.getKeyword())) {
String kw = query.getKeyword().toLowerCase();
String text = (item.getId() + item.getContent() + item.getWarningType()).toLowerCase();
String text = (item.getId() + item.getCategory() + item.getSubtype()
+ item.getRiskObject() + item.getContent()).toLowerCase();
if (!text.contains(kw)) {
return false;
}
}
if (StringUtils.hasText(query.getWarningType()) && !query.getWarningType().equals(item.getWarningType())) {
if (StringUtils.hasText(query.getType()) && !query.getType().equals(item.getCategory())) {
return false;
}
if (StringUtils.hasText(query.getLevel()) && !query.getLevel().equals(item.getLevel())) {
if (StringUtils.hasText(query.getSubtype()) && !query.getSubtype().equals(item.getSubtype())) {
return false;
}
if (StringUtils.hasText(query.getProcessStatus()) && !matchProcessStatus(query.getProcessStatus(), item.getStatus())) {
if (StringUtils.hasText(query.getStage()) && !query.getStage().equals(item.getStage())) {
return false;
}
return true;
}
private boolean matchProcessStatus(String queryStatus, String itemStatus) {
if (RegulatorRiskProcessStatusEnum.UNPROCESSED.getName().equals(queryStatus)) {
return Arrays.asList("未处理", "待确认").contains(itemStatus);
}
if (RegulatorRiskProcessStatusEnum.PROCESSING.getName().equals(queryStatus)) {
return "处理中".equals(itemStatus);
}
if (RegulatorRiskProcessStatusEnum.PROCESSED.getName().equals(queryStatus)) {
return Arrays.asList("已闭环", "已发函", "已提醒", "已处置").contains(itemStatus);
}
return false;
}
private String resolveStatus(RegulatorRiskHandleCmd cmd) {
if (StringUtils.hasText(cmd.getStatus())) {
return cmd.getStatus();
}
String type = cmd.getHandleType();
if (type.contains("闭环")) {
return "已闭环";
}
if (type.contains("发函")) {
return "已发函";
}
if (type.contains("提醒")) {
return "已提醒";
}
if (type.contains("转办") || type.contains("转备案")) {
return "处理中";
}
return "已处置";
}
private boolean isUntreated(String status) {
return Arrays.asList("未处理", "待确认", "处理中").contains(status);
}
private boolean isHandledToday(String status) {
return Arrays.asList("已闭环", "已发函", "已提醒", "已处置").contains(status);
}
private RegulatorRiskOverviewCO.StatCardCO stat(String label, String value, String hint) {
RegulatorRiskOverviewCO.StatCardCO card = new RegulatorRiskOverviewCO.StatCardCO();
card.setLabel(label);
@ -258,22 +116,17 @@ public class RegulatorRiskCenterController {
return card;
}
private RegulatorRiskMessageCO message(String id, String type, String level, String module,
List<String> fields, String content, String status, String moduleKey) {
private RegulatorRiskMessageCO message(String id, String category, String subtype, String riskObject,
List<String> sourceFields, String content, String stage, String orgStatus) {
RegulatorRiskMessageCO co = new RegulatorRiskMessageCO();
co.setId(id);
co.setWarningType(type);
co.setLevel(level);
co.setLevelName(levelName(level));
co.setSourceModule(module);
co.setSourceFields(fields);
co.setCategory(category);
co.setSubtype(subtype);
co.setRiskObject(riskObject);
co.setSourceFields(sourceFields);
co.setContent(content);
co.setStatus(status);
co.setSourceModuleKey(moduleKey);
co.setStage(stage);
co.setOrgStatus(orgStatus);
return co;
}
private String levelName(String level) {
return level;
}
}

View File

@ -14,27 +14,24 @@ public class RegulatorRiskMessageCO {
@ApiModelProperty("预警编号")
private String id;
@ApiModelProperty("预警类型")
private String warningType;
@ApiModelProperty(value = "预警大类", allowableValues = "资质预警,项目预警")
private String category;
@ApiModelProperty("预警等级")
private String level;
@ApiModelProperty(value = "预警子类", allowableValues = "资质条件保持异常,人员比例异常,属地材料待核验,项目启动超期,关键节点超期,项目人员异常,从业告知异常,现场勘查异常,过程控制/归档异常")
private String subtype;
@ApiModelProperty("等级名称:紧急/重要/一般")
private String levelName;
@ApiModelProperty("来源模块")
private String sourceModule;
@ApiModelProperty("风险对象")
private String riskObject;
@ApiModelProperty("来源字段")
private List<String> sourceFields;
@ApiModelProperty("预警内容")
@ApiModelProperty("触发内容")
private String content;
@ApiModelProperty("状态")
private String status;
@ApiModelProperty(value = "处理阶段", allowableValues = "未处理,已发机构,待复核,已闭环")
private String stage;
@ApiModelProperty("来源模块跳转标识")
private String sourceModuleKey;
@ApiModelProperty("机构端状态")
private String orgStatus;
}

View File

@ -14,9 +14,6 @@ public class RegulatorRiskOverviewCO {
@ApiModelProperty("统计卡片")
private List<StatCardCO> stats;
@ApiModelProperty("消息处理动作说明")
private String processGuide;
@Data
public static class StatCardCO {

View File

@ -1,32 +0,0 @@
package org.qinan.safetyeval.client.co.regulator;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
*
*/
@Data
public class RegulatorRiskPriorityAlertCO {
@ApiModelProperty("标题")
private String title;
@ApiModelProperty("描述")
private String description;
@ApiModelProperty("关联预警编号")
private String messageId;
@ApiModelProperty("级别danger/warning/info")
private String level;
@ApiModelProperty("预警类型")
private String warningType;
@ApiModelProperty("来源模块")
private String sourceModule;
@ApiModelProperty("消息状态")
private String status;
}

View File

@ -1,30 +0,0 @@
package org.qinan.safetyeval.client.dto.regulator;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
/**
*
*/
@Data
public class RegulatorRiskHandleCmd {
@NotBlank
@ApiModelProperty("预警编号")
private String id;
@NotBlank
@ApiModelProperty("处置方式:发函核查/转备案审核/要求整改/标记闭环/已发函/已提醒等")
private String handleType;
@ApiModelProperty("办理期限 yyyy-MM-dd")
private String deadline;
@ApiModelProperty("处置意见")
private String opinion;
@ApiModelProperty("处置后状态,不传则根据 handleType 推断")
private String status;
}

View File

@ -12,15 +12,15 @@ import org.qinan.safetyeval.client.dto.BasePageQuery;
@EqualsAndHashCode(callSuper = true)
public class RegulatorRiskMessagePageQuery extends BasePageQuery {
@ApiModelProperty("关键词:机构/人员/项目/预警编号")
@ApiModelProperty("关键词:机构/项目/人员/预警编号")
private String keyword;
@ApiModelProperty(value = "预警", allowableValues = "证书过期,证书临期,社保异常,人员离职,信息变更")
private String warningType;
@ApiModelProperty(value = "预警类", allowableValues = "资质预警,项目预警")
private String type;
@ApiModelProperty(value = "预警等级", allowableValues = "紧急,重要,一般")
private String level;
@ApiModelProperty(value = "预警子类", allowableValues = "资质条件保持异常,人员比例异常,属地材料待核验,项目启动超期,关键节点超期,项目人员异常,从业告知异常,现场勘查异常,过程控制/归档异常")
private String subtype;
@ApiModelProperty(value = "处理状态", allowableValues = "未处理,处理中,已处理")
private String processStatus;
@ApiModelProperty(value = "处理阶段", allowableValues = "未处理,已发机构,待复核,已闭环")
private String stage;
}

View File

@ -1,29 +0,0 @@
package org.qinan.safetyeval.client.dto.regulator;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
*
*/
@Data
public class RegulatorRiskPriorityAlertQuery {
@ApiModelProperty(value = "预警等级", allowableValues = "紧急,重要,一般")
private String level = "紧急";
@ApiModelProperty(value = "预警类型", allowableValues = "证书过期,证书临期,社保异常,人员离职,信息变更")
private String warningType;
@ApiModelProperty("来源模块")
private String sourceModule;
@ApiModelProperty("关键词:标题/预警编号/预警内容")
private String keyword;
@ApiModelProperty("仅未处理true 时筛选 未处理/待确认/处理中,默认 true")
private Boolean onlyUntreated = true;
@ApiModelProperty("返回条数上限,默认 2")
private Integer limit = 2;
}

View File

@ -1,42 +0,0 @@
package org.qinan.safetyeval.client.enums.regulator;
import java.util.Objects;
/**
* -
*/
public enum RegulatorRiskLevelEnum {
URGENT("紧急", "紧急"),
IMPORTANT("重要", "重要"),
NORMAL("一般", "一般"),
;
private final String code;
private final String name;
RegulatorRiskLevelEnum(String code, String name) {
this.code = code;
this.name = name;
}
public String getCode() {
return code;
}
public String getName() {
return name;
}
public static RegulatorRiskLevelEnum ofCode(String code) {
if (code == null) {
return null;
}
for (RegulatorRiskLevelEnum item : values()) {
if (Objects.equals(item.code, code)) {
return item;
}
}
return null;
}
}

View File

@ -1,36 +0,0 @@
package org.qinan.safetyeval.client.enums.regulator;
import java.util.Objects;
/**
* -
*/
public enum RegulatorRiskProcessStatusEnum {
UNPROCESSED("未处理"),
PROCESSING("处理中"),
PROCESSED("已处理"),
;
private final String name;
RegulatorRiskProcessStatusEnum(String name) {
this.name = name;
}
public String getName() {
return name;
}
public static RegulatorRiskProcessStatusEnum ofName(String name) {
if (name == null) {
return null;
}
for (RegulatorRiskProcessStatusEnum item : values()) {
if (Objects.equals(item.name, name)) {
return item;
}
}
return null;
}
}

View File

@ -1,38 +0,0 @@
package org.qinan.safetyeval.client.enums.regulator;
import java.util.Objects;
/**
* -
*/
public enum RegulatorRiskWarningTypeEnum {
CERT_EXPIRED("证书过期"),
CERT_EXPIRING("证书临期"),
SOCIAL_INSURANCE_ABNORMAL("社保异常"),
EMPLOYEE_RESIGNED("人员离职"),
INFO_CHANGED("信息变更"),
;
private final String name;
RegulatorRiskWarningTypeEnum(String name) {
this.name = name;
}
public String getName() {
return name;
}
public static RegulatorRiskWarningTypeEnum ofName(String name) {
if (name == null) {
return null;
}
for (RegulatorRiskWarningTypeEnum item : values()) {
if (Objects.equals(item.name, name)) {
return item;
}
}
return null;
}
}

View File

@ -1,4 +1,4 @@
<!doctype html><html lang="zh"><head data-built-info="@cqsjjb/scripts@2.0.0-rspack.2 Frontend_Env[production] Build_Date[2026/7/15 11:35:53] App_Identifier[safetyEval-h5]"><meta charset="UTF-8"/><meta name="renderer" content="webkit"/><meta http-equiv="X-UA-Compatible" content="IE=edge,Chrome=1"/><meta name="viewport" content="width=device-width,minimum-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover"><meta charset="UTF-8" name="referrer" content="strict-origin-when-cross-origin"/><title>大屏</title><script>(function () {
<!doctype html><html lang="zh"><head data-built-info="@cqsjjb/scripts@2.0.0-rspack.2 Frontend_Env[production] Build_Date[2026/7/16 10:30:23] App_Identifier[safetyEval-h5]"><meta charset="UTF-8"/><meta name="renderer" content="webkit"/><meta http-equiv="X-UA-Compatible" content="IE=edge,Chrome=1"/><meta name="viewport" content="width=device-width,minimum-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover"><meta charset="UTF-8" name="referrer" content="strict-origin-when-cross-origin"/><title>大屏</title><script>(function () {
const APP_ENV = {
antd: {
'ant-prefix': 'micro-temp',
@ -126,4 +126,4 @@
}
mergeParams();
})();
})();</script><script defer="defer" src="/safetyEval-h5/static/js/548.ac3036a0ff72bbda.js"></script><script defer="defer" src="/safetyEval-h5/static/js/551.40cd16b83ccef834.js"></script><script defer="defer" src="/safetyEval-h5/static/js/485.cc16547839dceff2.js"></script><script defer="defer" src="/safetyEval-h5/static/js/main.f98503f3c068bbb9.js"></script><link href="/safetyEval-h5/static/css/main.82ee4667fd2973b4.css" rel="stylesheet"></head><body><noscript>此网页需要开启JavaScript功能。</noscript><div id="root" style="width: 100%; height: 100%; position: relative;overflow-y: auto;"></div><script type="text/javascript">/* @cqsjjb/script 输出当前应用基本信息 */console.log("%c@cqsjjb/scripts@2.0.0-rspack.2 Frontend_Env[production] Build_Date[2026/7/15 11:35:53] App_Identifier[safetyEval-h5] Frontend_Branch[dev_1.0.1] Backend_Branch[<branch-name>]", "color: #1890ff; border-radius: 2px; padding: 0 4px; border: 1px solid #1890ff; background: #f9fcff")</script></body><script src="https://cesium.com/downloads/cesiumjs/releases/1.91/Build/Cesium/Cesium.js"></script><link href="https://cesium.com/downloads/cesiumjs/releases/1.91/Build/Cesium/Widgets/widgets.css" rel="stylesheet"></html>
})();</script><script defer="defer" src="/safetyEval-h5/static/js/548.ac3036a0ff72bbda.js"></script><script defer="defer" src="/safetyEval-h5/static/js/551.40cd16b83ccef834.js"></script><script defer="defer" src="/safetyEval-h5/static/js/485.cc16547839dceff2.js"></script><script defer="defer" src="/safetyEval-h5/static/js/main.f98503f3c068bbb9.js"></script><link href="/safetyEval-h5/static/css/main.82ee4667fd2973b4.css" rel="stylesheet"></head><body><noscript>此网页需要开启JavaScript功能。</noscript><div id="root" style="width: 100%; height: 100%; position: relative;overflow-y: auto;"></div><script type="text/javascript">/* @cqsjjb/script 输出当前应用基本信息 */console.log("%c@cqsjjb/scripts@2.0.0-rspack.2 Frontend_Env[production] Build_Date[2026/7/16 10:30:23] App_Identifier[safetyEval-h5] Frontend_Branch[dev] Backend_Branch[<branch-name>]", "color: #1890ff; border-radius: 2px; padding: 0 4px; border: 1px solid #1890ff; background: #f9fcff")</script></body><script src="https://cesium.com/downloads/cesiumjs/releases/1.91/Build/Cesium/Cesium.js"></script><link href="https://cesium.com/downloads/cesiumjs/releases/1.91/Build/Cesium/Widgets/widgets.css" rel="stylesheet"></html>

View File

@ -1,4 +1,4 @@
<!doctype html><html lang="zh"><head data-built-info="@cqsjjb/scripts@2.0.0-rspack.1 Frontend_Env[production] Build_Date[2026/7/15 17:30:37] App_Identifier[safetyEval]"><meta charset="UTF-8"/><meta name="renderer" content="webkit"/><meta http-equiv="X-UA-Compatible" content="IE=edge,Chrome=1"/><meta name="viewport" content="width=device-width,minimum-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover"><title>--</title><script>(function () {
<!doctype html><html lang="zh"><head data-built-info="@cqsjjb/scripts@2.0.0-rspack.1 Frontend_Env[production] Build_Date[2026/7/16 10:30:20] App_Identifier[safetyEval]"><meta charset="UTF-8"/><meta name="renderer" content="webkit"/><meta http-equiv="X-UA-Compatible" content="IE=edge,Chrome=1"/><meta name="viewport" content="width=device-width,minimum-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover"><title>--</title><script>(function () {
const APP_ENV = {
antd: {
'ant-prefix': 'micro-temp',
@ -89,4 +89,4 @@
},
}
}</script><script defer="defer" src="/safetyEval/static/js/323.fd0657fd2fffbe7a.js"></script><script defer="defer" src="/safetyEval/static/js/121.ae75e71830bf4ae0.js"></script><script defer="defer" src="/safetyEval/static/js/289.ab5c99a14babc2d4.js"></script><script defer="defer" src="/safetyEval/static/js/main.cf3854095b32e85a.js"></script><link href="/safetyEval/static/css/main.d4bcd75c2815b66b.css" rel="stylesheet"></head><body><noscript>此网页需要开启JavaScript功能。</noscript><div id="root" style="width: 100%; height: 100%; position: relative;overflow-y: auto"></div><script type="text/javascript">/* @cqsjjb/script 输出当前应用基本信息 */console.log("%c@cqsjjb/scripts@2.0.0-rspack.1 Frontend_Env[production] Build_Date[2026/7/15 17:30:37] App_Identifier[safetyEval] Frontend_Branch[dev] Backend_Branch[dev]", "color: #1890ff; border-radius: 2px; padding: 0 4px; border: 1px solid #1890ff; background: #f9fcff")</script></body></html>
}</script><script defer="defer" src="/safetyEval/static/js/323.fd0657fd2fffbe7a.js"></script><script defer="defer" src="/safetyEval/static/js/121.ae75e71830bf4ae0.js"></script><script defer="defer" src="/safetyEval/static/js/289.ab5c99a14babc2d4.js"></script><script defer="defer" src="/safetyEval/static/js/main.88ffaea5f7476e6c.js"></script><link href="/safetyEval/static/css/main.d4bcd75c2815b66b.css" rel="stylesheet"></head><body><noscript>此网页需要开启JavaScript功能。</noscript><div id="root" style="width: 100%; height: 100%; position: relative;overflow-y: auto"></div><script type="text/javascript">/* @cqsjjb/script 输出当前应用基本信息 */console.log("%c@cqsjjb/scripts@2.0.0-rspack.1 Frontend_Env[production] Build_Date[2026/7/16 10:30:20] App_Identifier[safetyEval] Frontend_Branch[dev] Backend_Branch[dev]", "color: #1890ff; border-radius: 2px; padding: 0 4px; border: 1px solid #1890ff; background: #f9fcff")</script></body></html>