You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

180 lines
7.3 KiB

# AssessReport 迁移方案(从 GetData.asmx.cs → yudao-server)
## 1. 旧接口梳理(assessReport.html 实际调用)
| 原方法 | 主要入参 | 返回 | 涉及表 / 处理 |
| --- | --- | --- | --- |
| `GetCondition(algorithm)` | `algorithm` | JSON(含 `model_score`、模式条件) | `model_condition` |
| `GetInfoV(p, version)` | 模型 ID、版本 | `Model_Info` JSON、点表 `pointInfo`、`trainTime` 等 | `model_view` / `model_version` |
| `GetReport(ID)` | 报告 ID | `report` JSON、`Model_Name` | 视图 `Assess_Report_View` |
| `GetModelDiagnosis_reverse_new(json, assess, alg, modelInfo)` | 评估请求体(点、幅度、限值、时间窗)、`alg`、`modelInfo` | 正/反向 `fdr/far/recon`、清洗耗时 | 调用外部 EXA/Python 服务 |
| `LF_GetAlgById(id)` | 模型 ID | 算法简称 | `MODEL_VIEW` |
| `insertReport(...)` | `report` JSON、模型/版本、得分、覆盖率、验证人、时间等 | bool | `Assess_Report_CFG` |
| `GetEXACleanDataMessagech(id, time, version)` | 模型 ID、时间范围、版本 | 清洗汇总(dead/limits/condition/envelopes) | 外部 Python `/api/test/clean_data` |
| `GetClrMsgDeadDtlch(item, time)` | 点号列表、时间段 | 死区清洗成功/占比 | EXA 清洗 |
| `GetConditionClrRateCH(condition, st, et)` | 模式条件、时间窗 | 各条件有效样本比 | EXA 历史数据 |
| `GetEnvelopesClrRateCH(condition, st, et)` | 包络条件、时间窗 | 各条件有效样本比 | EXA 历史数据 |
## 2. 新 REST 设计(建议)
Base Path:`/alert/assess-report`
- `GET /init`:入参 `modelId`、`version`、可选 `reportId/timeRange`。返回模型信息、点表、模式信息、默认参与预警点、底线分数。
- `GET /report/{id}`:读取历史报告。
- `POST /evaluate`:入参 `AssessEvaluateRequest`(点表、幅度、时间窗、模式),返回正/反向 `fdr/far/recon`、覆盖率、耗时。
- `POST /`:保存评估报告(包含得分、覆盖率、是否投入、报告 JSON)。
- `GET /clean/summary`:获取清洗汇总(对应 `GetEXACleanDataMessagech`)。
- `GET /clean/dead`:按点号返回死区清洗占比/结果。
- `GET /clean/condition-rate`、`/clean/envelope-rate`:模式/包络有效样本占比。
- `GET /condition`:按算法返回评估底线、模式条件。
## 3. Controller / Service / Mapper 代码骨架(yudao 风格)
```java
// controller/admin/model/AssessReportController.java
@RestController
@RequestMapping("/alert/assess-report")
@RequiredArgsConstructor
public class AssessReportController {
private final AssessReportService assessReportService;
@GetMapping("/init")
public CommonResult<AssessInitRespVO> init(AssessInitReqVO reqVO) {
return success(assessReportService.init(reqVO));
}
@GetMapping("/report/{id}")
public CommonResult<AssessReportDetailVO> detail(@PathVariable Long id) {
return success(assessReportService.getReport(id));
}
@PostMapping("/evaluate")
public CommonResult<AssessEvaluateRespVO> evaluate(@RequestBody AssessEvaluateReqVO reqVO) {
return success(assessReportService.evaluate(reqVO));
}
@PostMapping
public CommonResult<Boolean> save(@RequestBody AssessReportCreateReqVO reqVO) {
return success(assessReportService.saveReport(reqVO));
}
@GetMapping("/clean/summary")
public CommonResult<AssessCleanSummaryVO> cleanSummary(AssessCleanQueryReqVO reqVO) {
return success(assessReportService.cleanSummary(reqVO));
}
}
```
```java
// service接口
public interface AssessReportService {
AssessInitRespVO init(AssessInitReqVO reqVO);
AssessReportDetailVO getReport(Long id);
AssessEvaluateRespVO evaluate(AssessEvaluateReqVO reqVO);
Boolean saveReport(AssessReportCreateReqVO reqVO);
AssessCleanSummaryVO cleanSummary(AssessCleanQueryReqVO reqVO);
}
// service实现关键片段
@Service
@RequiredArgsConstructor
public class AssessReportServiceImpl implements AssessReportService {
private final AssessReportMapper assessReportMapper;
private final ModelMapper modelMapper;
private final RemoteExaClient remoteExaClient; // 封装 EXA/Python HTTP 调用
@Override
public AssessInitRespVO init(AssessInitReqVO reqVO) {
// 1) 模型信息&版本解析;2) pointInfo 过滤 lock=false; 3) 构造默认 assess 列表
// 4) 读取底线 model_score
}
@Override
public AssessEvaluateRespVO evaluate(AssessEvaluateReqVO reqVO) {
// 组织 payload 适配原 json(Test_Data、dead/limit/uplow、number_fault_variable 等)
// 调用 remoteExaClient.assess(...); 映射回 fdr/far/recon
}
@Override
public Boolean saveReport(AssessReportCreateReqVO reqVO) {
AssessReportDO report = AssessReportConvert.INSTANCE.convert(reqVO);
return assessReportMapper.insert(report) > 0;
}
}
```
```java
// 数据对象 & Mapper
@TableName("alert_assess_report")
@Data
public class AssessReportDO extends BaseDO {
@TableId
private Long id;
private Long modelId;
private String version;
private String reportJson;
private BigDecimal score;
private BigDecimal coverRange;
private String validFlag; // '是'/'否'
private String identifier;
private String verifier;
private LocalDateTime assessTime;
private String conditionName;
}
@Mapper
public interface AssessReportMapper extends BaseMapperX<AssessReportDO> {
}
```
## 4. MySQL 表结构建议
```sql
CREATE TABLE alert_assess_report (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
model_id BIGINT NOT NULL,
version VARCHAR(64) NOT NULL,
report_json JSON NOT NULL,
score DECIMAL(8,2) NOT NULL,
cover_range DECIMAL(8,4) DEFAULT 0,
valid_flag CHAR(1) DEFAULT '0', -- 1:是,0:否
identifier VARCHAR(64) NOT NULL,
verifier VARCHAR(64),
assess_time DATETIME NOT NULL,
condition_name VARCHAR(128),
creator VARCHAR(64),
create_time DATETIME DEFAULT CURRENT_TIMESTAMP,
updater VARCHAR(64),
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
CREATE TABLE alert_model_condition (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
algorithm VARCHAR(32) NOT NULL,
condition_text TEXT,
model_score DECIMAL(8,2),
UNIQUE KEY uk_alg (algorithm)
);
```
视图/版本:`model_view`、`model_version` 迁移到 MySQL 后保留字段 `model_info` (JSON)、`cur_version` 等即可支撑 init 查询。
## 5. T-SQL → MySQL 改写要点
- `SELECT TOP 1 ... ORDER BY``SELECT ... ORDER BY ... LIMIT 1`
- `NVARCHAR``VARCHAR`,`DATETIME` 兼容;`bit` → `tinyint(1)`;`float` → `double`
- 日期加减:`DATEADD(hour, -24, GETDATE())` → `DATE_SUB(NOW(), INTERVAL 24 HOUR)`
- 字符拼接:`'a' + b` → `CONCAT('a', b)`
- 布尔:`true/false` 改为 `1/0`
## 6. 清洗/评估逻辑迁移提示
- EXA/Python 调用封装在 `RemoteExaClient`,使用 `WebClient`/`RestTemplate`,增加超时、异常转译(返回 `CommonResult`)。
- 模式/包络有效样本占比 `GetConditionClrRateCH`、`GetEnvelopesClrRateCH` 可重写为:查询历史表(时间戳+值),在 Java 端计算满足条件的计数后返回数组。
- 报告得分计算(前端已有,同步可在服务端实现确保导出一致性)。
## 7. 统一返回与异常
- 统一 `CommonResult<T>`,非法参数返回 `PARAMS_ERROR`,外部服务异常包装为 `INTERNAL_SERVER_ERROR`
- 导出/下载接口可返回临时文件 token 或直流写出。