package com.battery.business.web; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.ruoyi.common.annotation.Log; import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.enums.BusinessType; import com.battery.business.domain.TTest; import com.battery.business.domain.TTestBattery; import com.battery.business.domain.TTestChannelBinding; import com.battery.business.domain.TTestCollectorChannel; import com.battery.business.domain.TTestWarningThreshold; import com.battery.business.test.dto.TestConfigurationDto; import com.battery.business.test.dto.TestBatteryBindingDto; import com.battery.business.test.dto.ThresholdDto; import com.battery.business.domain.TTestLogicStepMapping; import com.battery.business.domain.TTestConsoleDetail; import com.battery.business.domain.TTestDataRevisionAction; import com.battery.business.domain.DataRevisionItem; import com.battery.business.service.ITTestService; import com.battery.business.service.ITestConsoleDataService; import com.battery.business.service.ITestDataQueryService; /** 测试管理 Controller。 */ @RestController @RequestMapping("/system/test") public class TTestController extends BaseController { @Autowired private ITTestService testService; @Autowired private ITestConsoleDataService consoleDataService; @Autowired private ITestDataQueryService testDataQueryService; @PreAuthorize("@ss.hasAnyPermi('system:test:add,system:test:edit')") @GetMapping("/options") public AjaxResult options() { return success(testService.selectConfigurationOptions()); } @PreAuthorize("@ss.hasPermi('system:test:list')") @GetMapping("/list") public TableDataInfo list(TTest test) { startPage(); List list = testService.selectTestList(test); return getDataTable(list); } @PreAuthorize("@ss.hasPermi('system:test:query')") @GetMapping("/{testId}") public AjaxResult getInfo(@PathVariable Long testId) { return success(testService.selectTestById(testId)); } @PreAuthorize("@ss.hasPermi('system:test:add')") @Log(title = "测试管理", businessType = BusinessType.INSERT) @PostMapping public AjaxResult add(@Validated @RequestBody TestConfigurationDto request) { TTest test = toDomain(request); test.setOperatorId(getUserId()); test.setCreatorId(getUserId()); test.setCreateBy(getUsername()); Long testId = testService.createTest(test); return success(testService.selectTestById(testId)); } @PreAuthorize("@ss.hasPermi('system:test:edit')") @Log(title = "测试管理", businessType = BusinessType.UPDATE) @PutMapping public AjaxResult edit(@Validated @RequestBody TestConfigurationDto request) { TTest test = toDomain(request); test.setOperatorId(getUserId()); test.setUpdateBy(getUsername()); testService.updateTest(test); return success(testService.selectTestById(test.getTestId())); } @PreAuthorize("@ss.hasPermi('system:test:start')") @Log(title = "测试管理", businessType = BusinessType.UPDATE) @PutMapping("/start") public AjaxResult start(@RequestParam Long testId) { testService.startReception(testId, getUserId(), getUsername()); return success(testService.selectTestById(testId)); } /** 独立的开始接收动作;只改变系统数据归属,不向设备发送控制命令。 */ @PreAuthorize("@ss.hasPermi('system:test:start')") @Log(title = "测试数据接收", businessType = BusinessType.UPDATE) @PostMapping("/{testId}/reception/start") public AjaxResult startReception(@PathVariable Long testId) { testService.startReception(testId, getUserId(), getUsername()); return success(testService.selectTestById(testId)); } /** 独立暂停接收动作;停止该测试数据请求,不向设备发送控制命令。 */ @PreAuthorize("@ss.hasPermi('system:test:pause')") @Log(title = "测试数据接收", businessType = BusinessType.UPDATE) @PostMapping("/{testId}/reception/pause") public AjaxResult pauseReception(@PathVariable Long testId) { testService.pauseReception(testId, getUserId(), getUsername()); return success(testService.selectTestById(testId)); } /** 独立继续接收动作;恢复该测试数据请求,不向设备发送控制命令。 */ @PreAuthorize("@ss.hasPermi('system:test:resume')") @Log(title = "测试数据接收", businessType = BusinessType.UPDATE) @PostMapping("/{testId}/reception/resume") public AjaxResult resumeReception(@PathVariable Long testId) { testService.resumeReception(testId, getUserId(), getUsername()); return success(testService.selectTestById(testId)); } /** 独立停止测试动作;进入不可恢复终态且不向设备发送控制命令。 */ @PreAuthorize("@ss.hasPermi('system:test:stop')") @Log(title = "停止测试", businessType = BusinessType.UPDATE) @PostMapping("/{testId}/stop") public AjaxResult stopTest(@PathVariable Long testId) { testService.stopTest(testId, getUserId(), getUsername()); return success(testService.selectTestById(testId)); } /** 人工结束接收动作别名;与停止测试共用停止请求并进入不可恢复终态的事务。 */ @PreAuthorize("@ss.hasPermi('system:test:stop')") @Log(title = "人工结束接收", businessType = BusinessType.UPDATE) @PostMapping("/{testId}/reception/end") public AjaxResult endReception(@PathVariable Long testId) { testService.stopTest(testId, getUserId(), getUsername()); return success(testService.selectTestById(testId)); } /** 保存当前测试的逻辑工步合并规则,不改写检测柜原始工步。 */ @PreAuthorize("@ss.hasPermi('system:test:edit')") @Log(title = "测试工步设置", businessType = BusinessType.UPDATE) @PutMapping("/{testId}/logic-step-mappings") public AjaxResult saveLogicStepMappings(@PathVariable Long testId, @RequestBody List mappings) { testService.saveLogicStepMappings(testId, mappings, getUserId(), getUsername()); return success(testService.selectTestById(testId)); } /** 保存工步图表测试详情当前最新版,不参与测试配置、统计或审计。 */ @PreAuthorize("@ss.hasPermi('system:test:edit')") @PutMapping("/{testId}/console-detail") public AjaxResult saveConsoleDetail(@PathVariable Long testId, @RequestBody TTestConsoleDetail detail) { testService.saveConsoleDetail(testId, detail, getUserId(), getUsername()); return success(testService.selectTestById(testId)); } /** 查询当前测试成功接收的检测柜与采集器实时观测。 */ @PreAuthorize("@ss.hasPermi('system:test:query')") @GetMapping("/{testId}/data/records") public AjaxResult persistedRecords(@PathVariable Long testId) { return success(testDataQueryService.records(testId)); } /** 只查询当前测试持久化采样汇总出的工步事实。 */ @PreAuthorize("@ss.hasPermi('system:test:query')") @GetMapping("/{testId}/data/steps") public AjaxResult persistedSteps(@PathVariable Long testId) { return success(testDataQueryService.steps(testId)); } /** 只查询当前测试持久化采样汇总出的循环事实。 */ @PreAuthorize("@ss.hasPermi('system:test:query')") @GetMapping("/{testId}/data/cycles") public AjaxResult persistedCycles(@PathVariable Long testId) { return success(testDataQueryService.cycles(testId)); } /** 一次提交编辑、导入或删除;三 Sheet 按数据类型分别追加修订,共享同一事务。 */ @PreAuthorize("@ss.hasPermi('system:test:edit')") @Log(title = "测试控制台数据修订", businessType = BusinessType.UPDATE) @PostMapping("/{testId}/console-data/actions") public AjaxResult dataAction(@PathVariable Long testId, @RequestBody ConsoleDataActionRequest request) { if (request == null) return error("数据操作不能为空"); TTestDataRevisionAction action = new TTestDataRevisionAction(); action.setTestId(testId); action.setDataType(request.dataType()); action.setOperationType(request.operationType()); action.setScopeSummary(request.scopeSummary()); action.setIdentitySummary(request.identitySummary()); action.setChangesSummary(request.changesSummary()); action.setReason(request.reason()); action.setOperatorId(getUserId()); action.setOperatorName(getUsername()); Long actionId = consoleDataService.submitAction(action, request.overrides() == null ? java.util.Collections.emptyList() : request.overrides()); return success().put("actionId", actionId).put("actionIds", action.getActionIds()) .put("importedCount", action.getImportedCount()).put("skippedCount", action.getSkippedCount()); } public record ConsoleDataActionRequest(String dataType, String operationType, String scopeSummary, String identitySummary, String changesSummary, String reason, List overrides) { } @PreAuthorize("@ss.hasPermi('system:test:remove')") @DeleteMapping("/{testIds}") public AjaxResult remove(@PathVariable Long[] testIds) { return toAjax(testService.deleteTestByIds(testIds, getUserId(), getUsername())); } /** 将测试配置 DTO 转换为现有测试服务模型;计划工步等废止字段不再进入服务。 */ private TTest toDomain(TestConfigurationDto request) { if (request == null) return null; TTest test = new TTest(); test.setTestId(request.testId()); test.setTestName(request.testName()); test.setPrincipalId(request.principalId()); test.setTestTypeId(request.testTypeId()); test.setTestPurpose(request.testPurpose()); test.setMonitorTimeoutMinutes(request.monitorTimeoutMinutes()); test.setRemark(request.remark()); java.util.List batteries = new java.util.ArrayList<>(); if (request.batteries() != null) for (TestBatteryBindingDto item : request.batteries()) { if (item == null) continue; TTestBattery battery = new TTestBattery(); battery.setTestBatteryId(item.resolvedTestBatteryId()); battery.setGroupId(item.groupId()); battery.setBatteryNo(item.batteryNo()); battery.setCollectorId(item.collectorId()); if (item.resolvedCabinetChannel() != null) { TTestChannelBinding binding = new TTestChannelBinding(); binding.setTestBatteryId(item.resolvedTestBatteryId()); binding.setChannelId(item.resolvedCabinetChannel().channelId()); binding.setExpectedBarcode(item.resolvedCabinetChannel().expectedBarcode()); battery.setBinding(binding); } java.util.List channels = new java.util.ArrayList<>(); if (item.collectorChannels() != null) for (TestBatteryBindingDto.CollectorChannelDto channel : item.collectorChannels()) { if (channel == null) continue; TTestCollectorChannel mapping = new TTestCollectorChannel(); mapping.setTestBatteryId(item.resolvedTestBatteryId()); mapping.setCollectorId(item.collectorId()); mapping.setMeasurementCode(channel.measurementCode()); mapping.setMeasurementName(channel.measurementName()); mapping.setChannelCode(channel.channelCode()); channels.add(mapping); } battery.setCollectorChannels(channels); batteries.add(battery); } test.setBatteries(batteries); java.util.List thresholds = new java.util.ArrayList<>(); if (request.thresholds() != null) for (ThresholdDto item : request.thresholds()) { if (item == null) continue; TTestWarningThreshold threshold = new TTestWarningThreshold(); threshold.setMetricCode(item.metricCode()); threshold.setMinValue(item.minValue()); threshold.setMaxValue(item.maxValue()); threshold.setUnit(item.unit()); threshold.setSeverity(item.severity()); thresholds.add(threshold); } test.setThresholds(thresholds); return test; } }