diff --git a/klp-wms/src/main/java/com/klp/service/impl/ImageRecognitionServiceImpl.java b/klp-wms/src/main/java/com/klp/service/impl/ImageRecognitionServiceImpl.java index f011bca3..1499ad11 100644 --- a/klp-wms/src/main/java/com/klp/service/impl/ImageRecognitionServiceImpl.java +++ b/klp-wms/src/main/java/com/klp/service/impl/ImageRecognitionServiceImpl.java @@ -116,16 +116,19 @@ public class ImageRecognitionServiceImpl implements IImageRecognitionService { // 解析识别结果 try { - Map structuredResult = parseBomResponse(aiResponse); + // 直接解析属性数组 + List attributes = parseAttributesResponse(aiResponse); + result.setAttributes(attributes); + + // 构建结构化结果 + Map structuredResult = new HashMap<>(); + structuredResult.put("attributes", attributes); + structuredResult.put("summary", "材料质保单识别结果"); + structuredResult.put("totalItems", attributes.size()); result.setStructuredResult(structuredResult); - // 提取BOM项目列表 - List bomItems = extractBomItems(structuredResult); - result.setBomItems(bomItems); - - // 提取属性列表 - List attributes = extractAttributes(structuredResult); - result.setAttributes(attributes); + // BOM项目为空,因为这是质保单识别 + result.setBomItems(new ArrayList<>()); } catch (Exception e) { log.warn("解析识别响应失败: {}", e.getMessage()); @@ -345,13 +348,19 @@ public class ImageRecognitionServiceImpl implements IImageRecognitionService { */ private String buildBomPrompt(ImageRecognitionBo bo) { StringBuilder prompt = new StringBuilder(); - prompt.append("请仔细分析这张图片中的内容,并提取所有相关信息:\n\n"); - prompt.append("【识别要求】\n"); - prompt.append("1. 如果图片包含BOM(物料清单)信息,请提取原材料ID、名称、数量、单位等\n"); - prompt.append("2. 如果图片包含其他类型的信息(如检验报告、产品信息等),请提取所有相关属性\n"); - prompt.append("3. 识别图片中的所有文字信息,包括标题、内容、表格数据等\n"); - prompt.append("4. 提取关键信息点,如产品名称、规格参数、检验结果等\n"); - prompt.append("5. 确保信息的准确性和完整性\n\n"); + prompt.append("这是一张材料质保单的图片。请从表格、文字排布中提取有用的信息,返回其中所有可以被识别为字段名 + 字段值的键值对。\n\n"); + prompt.append("要求如下:\n\n"); + prompt.append("1. 忽略标题、编号、日期等通用信息,不要作为键值对输出;\n"); + prompt.append("2. 仅提取\"字段名 + 字段值\"形式的内容,且字段名可以是如\"钢卷号\"、\"规格\"、\"净重\"、\"材质\"、\"下工序\"、\"生产班组\"、\"生产日期\"等;\n"); + prompt.append("3. 字段不固定,根据图像内容自行判断,但要尽量提取所有;\n"); + prompt.append("4. 返回格式统一为 JSON 数组,格式如下:\n"); + prompt.append("[\n"); + prompt.append(" { \"attrKey\": \"字段名\", \"attrValue\": \"字段值\" },\n"); + prompt.append(" ...\n"); + prompt.append("]\n"); + prompt.append("5. 如有值缺失或为空的字段,仍保留字段,value 留空字符串;\n"); + prompt.append("6. 严格按照图像中文字布局顺序返回;\n"); + prompt.append("7. 只输出 JSON 结果,不需要解释或说明;\n\n"); if (bo.getProductId() != null) { prompt.append("【产品信息】\n"); @@ -362,30 +371,6 @@ public class ImageRecognitionServiceImpl implements IImageRecognitionService { prompt.append("【自定义要求】\n"); prompt.append(bo.getCustomPrompt()).append("\n\n"); } - - prompt.append("【输出格式】\n"); - prompt.append("请按以下JSON格式输出识别结果:\n"); - prompt.append("{\n"); - prompt.append(" \"bomItems\": [\n"); - prompt.append(" {\n"); - prompt.append(" \"rawMaterialId\": \"原材料ID\",\n"); - prompt.append(" \"rawMaterialName\": \"原材料名称\",\n"); - prompt.append(" \"quantity\": 数量,\n"); - prompt.append(" \"unit\": \"单位\",\n"); - prompt.append(" \"specification\": \"规格\",\n"); - prompt.append(" \"remark\": \"备注\"\n"); - prompt.append(" }\n"); - prompt.append(" ],\n"); - prompt.append(" \"attributes\": [\n"); - prompt.append(" {\n"); - prompt.append(" \"attrKey\": \"属性名称\",\n"); - prompt.append(" \"attrValue\": \"属性值\"\n"); - prompt.append(" }\n"); - prompt.append(" ],\n"); - prompt.append(" \"summary\": \"内容总结\",\n"); - prompt.append(" \"totalItems\": 总项目数\n"); - prompt.append("}\n\n"); - prompt.append("请将识别到的所有信息整理成属性数组,每个属性包含attrKey(属性名称)和attrValue(属性值)。"); return prompt.toString(); } @@ -439,7 +424,53 @@ public class ImageRecognitionServiceImpl implements IImageRecognitionService { } /** - * 解析BOM响应 + * 解析属性数组响应 + */ + private List parseAttributesResponse(String response) { + try { + // 尝试直接解析JSON数组 + List> attrList = objectMapper.readValue(response, + objectMapper.getTypeFactory().constructCollectionType(List.class, Map.class)); + + List attributes = new ArrayList<>(); + for (Map attr : attrList) { + ImageRecognitionVo.AttributeVo attribute = new ImageRecognitionVo.AttributeVo(); + attribute.setAttrKey((String) attr.get("attrKey")); + attribute.setAttrValue((String) attr.get("attrValue")); + attributes.add(attribute); + } + return attributes; + + } catch (JsonProcessingException e) { + // 如果直接解析失败,尝试提取JSON数组部分 + Pattern jsonArrayPattern = Pattern.compile("\\[[\\s\\S]*\\]"); + Matcher matcher = jsonArrayPattern.matcher(response); + if (matcher.find()) { + try { + List> attrList = objectMapper.readValue(matcher.group(), + objectMapper.getTypeFactory().constructCollectionType(List.class, Map.class)); + + List attributes = new ArrayList<>(); + for (Map attr : attrList) { + ImageRecognitionVo.AttributeVo attribute = new ImageRecognitionVo.AttributeVo(); + attribute.setAttrKey((String) attr.get("attrKey")); + attribute.setAttrValue((String) attr.get("attrValue")); + attributes.add(attribute); + } + return attributes; + + } catch (JsonProcessingException ex) { + log.warn("无法解析属性响应为JSON数组: {}", response); + return new ArrayList<>(); + } + } + log.warn("无法解析属性响应: {}", response); + return new ArrayList<>(); + } + } + + /** + * 解析BOM响应(保留用于兼容性) */ private Map parseBomResponse(String response) { try { diff --git a/klp-wms/src/main/java/com/klp/test/ImageRecognitionTest.java b/klp-wms/src/main/java/com/klp/test/ImageRecognitionTest.java deleted file mode 100644 index 25b646df..00000000 --- a/klp-wms/src/main/java/com/klp/test/ImageRecognitionTest.java +++ /dev/null @@ -1,118 +0,0 @@ -package com.klp.test; - -import com.klp.domain.bo.ImageRecognitionBo; -import com.klp.domain.vo.ImageRecognitionVo; -import com.klp.service.IImageRecognitionService; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.boot.CommandLineRunner; -import org.springframework.stereotype.Component; - -import java.util.HashMap; -import java.util.Map; - -/** - * 图片识别功能测试类 - * - * @author klp - * @date 2025-01-27 - */ -@Slf4j -@Component -@RequiredArgsConstructor -public class ImageRecognitionTest implements CommandLineRunner { - - private final IImageRecognitionService imageRecognitionService; - - @Override - public void run(String... args) throws Exception { - log.info("开始测试图片识别功能..."); - - // 测试AI连接 - testAiConnection(); - - // 测试文字识别 - testTextRecognition(); - - // 测试BOM识别 - testBomRecognition(); - - log.info("图片识别功能测试完成"); - } - - /** - * 测试AI连接 - */ - private void testAiConnection() { - log.info("测试AI连接..."); - try { - Map result = imageRecognitionService.testAiConnection(); - if (Boolean.TRUE.equals(result.get("success"))) { - log.info("AI连接测试成功: {}", result.get("message")); - } else { - log.error("AI连接测试失败: {}", result.get("message")); - } - } catch (Exception e) { - log.error("AI连接测试异常", e); - } - } - - /** - * 测试文字识别 - */ - private void testTextRecognition() { - log.info("测试文字识别..."); - try { - ImageRecognitionBo bo = new ImageRecognitionBo(); - bo.setImageUrl("https://via.placeholder.com/400x300/000000/FFFFFF?text=Test+Text"); - bo.setRecognitionType("text"); - bo.setEnableVoting(false); - - ImageRecognitionVo result = imageRecognitionService.recognizeText(bo); - log.info("文字识别结果: {}", result.getRecognizedText()); - log.info("识别状态: {}", result.getStatus()); - log.info("处理时间: {}ms", result.getProcessingTime()); - } catch (Exception e) { - log.error("文字识别测试异常", e); - } - } - - /** - * 测试BOM识别 - */ - private void testBomRecognition() { - log.info("测试BOM识别..."); - try { - ImageRecognitionBo bo = new ImageRecognitionBo(); - bo.setImageUrl("https://via.placeholder.com/400x300/000000/FFFFFF?text=BOM+Test"); - bo.setRecognitionType("bom"); - bo.setEnableVoting(false); - bo.setProductId(1L); - - ImageRecognitionVo result = imageRecognitionService.recognizeBom(bo); - log.info("BOM识别结果: {}", result.getRecognizedText()); - log.info("识别状态: {}", result.getStatus()); - log.info("处理时间: {}ms", result.getProcessingTime()); - - if (result.getBomItems() != null) { - log.info("BOM项目数量: {}", result.getBomItems().size()); - for (ImageRecognitionVo.BomItemVo item : result.getBomItems()) { - log.info("BOM项目: {} - {} {} {}", - item.getRawMaterialName(), - item.getQuantity(), - item.getUnit(), - item.getSpecification()); - } - } - - if (result.getAttributes() != null) { - log.info("属性数量: {}", result.getAttributes().size()); - for (ImageRecognitionVo.AttributeVo attr : result.getAttributes()) { - log.info("属性: {} = {}", attr.getAttrKey(), attr.getAttrValue()); - } - } - } catch (Exception e) { - log.error("BOM识别测试异常", e); - } - } -} \ No newline at end of file