refactor(energy): 简化事件驱动系统(7个→3个)

- 删除旧事件:BillApprovedEvent, BillCreatedEvent, DeductionCompletedEvent, DetailAuditedEvent, DetailCreatedEvent, RecordMatchedEvent
- 新增事件:BillAuditPassedEvent, DetailAuditPassedEvent
- 保留事件:RecordImportedEvent
- 更新监听器:AccountEventListener, BillEventListener, DetailEventListener
- 清理代码中的旧事件引用和注释

优化原则:前端简单,后端健壮
事件流程:导入→匹配→生成明细→审核→扣款→生成账单→结算
This commit is contained in:
kkfluous
2026-03-16 12:53:14 +08:00
parent f5062cec22
commit 2f38a703f9
167 changed files with 9876 additions and 824 deletions

View File

@@ -1,14 +1,14 @@
package cn.iocoder.yudao.module.ocr.api;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.ocr.api.dto.VehicleLicenseReqDTO;
import cn.iocoder.yudao.module.ocr.api.dto.VehicleLicenseRespDTO;
import cn.iocoder.yudao.module.ocr.enums.ApiConstants;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestBody;
/**
* OCR 识别 API 接口
@@ -23,10 +23,7 @@ public interface OcrApi {
@PostMapping(PREFIX + "/vehicle-license")
@Operation(summary = "识别行驶证(提供给内部模块)")
@Parameter(name = "imageData", description = "图片数据Base64编码", required = true)
@Parameter(name = "provider", description = "OCR厂商可选默认使用配置的默认厂商", example = "baidu")
CommonResult<VehicleLicenseRespDTO> recognizeVehicleLicense(
@RequestParam("imageData") String imageData,
@RequestParam(value = "provider", required = false) String provider);
@RequestBody VehicleLicenseReqDTO reqDTO);
}

View File

@@ -0,0 +1,16 @@
package cn.iocoder.yudao.module.ocr.api.dto;
import lombok.Data;
import java.io.Serializable;
@Data
public class VehicleLicenseReqDTO implements Serializable {
/** 图片数据Base64编码 */
private String imageData;
/** OCR厂商可选 */
private String provider;
}

View File

@@ -1,25 +1,22 @@
package cn.iocoder.yudao.module.ocr.api;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.ocr.api.dto.VehicleLicenseReqDTO;
import cn.iocoder.yudao.module.ocr.api.dto.VehicleLicenseRespDTO;
import cn.iocoder.yudao.module.ocr.framework.ocr.core.client.OcrClient;
import cn.iocoder.yudao.module.ocr.framework.ocr.core.client.OcrClientFactory;
import cn.iocoder.yudao.module.ocr.convert.ocr.OcrConvert;
import cn.iocoder.yudao.module.ocr.framework.ocr.core.result.VehicleLicenseResult;
import cn.iocoder.yudao.module.ocr.service.ocr.OcrService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RestController;
import jakarta.annotation.Resource;
import java.util.Base64;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
/**
* OCR 识别 API 实现类
*
* @author 芋道源码
*/
@RestController
@Validated
@@ -27,37 +24,23 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
public class OcrApiImpl implements OcrApi {
@Resource
private OcrClientFactory ocrClientFactory;
private OcrService ocrService;
@Override
public CommonResult<VehicleLicenseRespDTO> recognizeVehicleLicense(String imageData, String provider) {
long startTime = System.currentTimeMillis();
public CommonResult<VehicleLicenseRespDTO> recognizeVehicleLicense(VehicleLicenseReqDTO reqDTO) {
try {
// Base64 解码图片数据
byte[] imageBytes = Base64.getDecoder().decode(reqDTO.getImageData());
log.info("[recognizeVehicleLicense][开始识别行驶证provider{},数据长度:{}]",
provider, imageData != null ? imageData.length() : 0);
// 调用识别服务
VehicleLicenseResult result = ocrService.recognizeVehicleLicense(imageBytes, reqDTO.getProvider());
// Base64 解码图片数据
byte[] imageBytes = Base64.decode(imageData);
// 获取 OCR 客户端
OcrClient ocrClient;
if (StrUtil.isNotBlank(provider)) {
ocrClient = ocrClientFactory.getClient(provider);
} else {
ocrClient = ocrClientFactory.getDefaultClient();
// 转换并返回
return success(OcrConvert.INSTANCE.convertDto(result));
} catch (Exception e) {
log.error("[recognizeVehicleLicense][识别行驶证失败]", e);
throw new RuntimeException("识别行驶证失败: " + e.getMessage());
}
// 调用识别
VehicleLicenseResult result = ocrClient.recognizeVehicleLicense(imageBytes);
// 转换为 DTO
VehicleLicenseRespDTO respDTO = BeanUtils.toBean(result, VehicleLicenseRespDTO.class);
long costTime = System.currentTimeMillis() - startTime;
log.info("[recognizeVehicleLicense][识别完成,耗时:{}msVIN{},车牌号:{}]",
costTime, respDTO.getVin(), respDTO.getPlateNo());
return success(respDTO);
}
}

View File

@@ -1,5 +1,6 @@
package cn.iocoder.yudao.module.ocr.convert.ocr;
import cn.iocoder.yudao.module.ocr.api.dto.VehicleLicenseRespDTO;
import cn.iocoder.yudao.module.ocr.controller.admin.ocr.vo.VehicleLicenseRespVO;
import cn.iocoder.yudao.module.ocr.framework.ocr.core.result.VehicleLicenseResult;
import org.mapstruct.Mapper;
@@ -14,8 +15,13 @@ public interface OcrConvert {
OcrConvert INSTANCE = Mappers.getMapper(OcrConvert.class);
/**
* 转换行驶证识别结果
* 转换行驶证识别结果Controller 使用)
*/
VehicleLicenseRespVO convert(VehicleLicenseResult result);
/**
* 转换行驶证识别结果API 使用)
*/
VehicleLicenseRespDTO convertDto(VehicleLicenseResult result);
}

View File

@@ -0,0 +1,26 @@
package cn.iocoder.yudao.module.ocr.framework.security.config;
import cn.iocoder.yudao.framework.security.config.AuthorizeRequestsCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.AuthorizeHttpRequestsConfigurer;
/**
* OCR 模块的 Security 配置
*/
@Configuration
public class SecurityConfiguration {
@Bean
public AuthorizeRequestsCustomizer authorizeRequestsCustomizer() {
return new AuthorizeRequestsCustomizer() {
@Override
public void customize(AuthorizeHttpRequestsConfigurer<HttpSecurity>.AuthorizationManagerRequestMatcherRegistry registry) {
// OCR 识别接口需要认证
registry.requestMatchers("/admin-api/ocr/**").authenticated();
}
};
}
}

View File

@@ -0,0 +1 @@
cn.iocoder.yudao.module.ocr.framework.ocr.config.OcrAutoConfiguration