From 053179a36542998b7c47d6f3385b54dd96fc19eb Mon Sep 17 00:00:00 2001 From: wangfukang <15630117759@163.com> Date: Thu, 16 May 2024 12:45:16 +0800 Subject: [PATCH] =?UTF-8?q?ai=E8=AF=86=E5=88=AB=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/PurchaseOcrPictureServiceImpl.java | 1 + .../java/cc/hiver/mall/utils/AliOcrUtil.java | 110 ++++++++++++------ .../mapper/PurchaseOcrPictureMapper.xml | 4 +- 3 files changed, 80 insertions(+), 35 deletions(-) diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/purchaseocr/service/impl/PurchaseOcrPictureServiceImpl.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/purchaseocr/service/impl/PurchaseOcrPictureServiceImpl.java index 08b2a17d..8426a298 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/purchaseocr/service/impl/PurchaseOcrPictureServiceImpl.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/purchaseocr/service/impl/PurchaseOcrPictureServiceImpl.java @@ -107,6 +107,7 @@ public class PurchaseOcrPictureServiceImpl implements PurchaseOcrPictureService addPurchaseOcrPicture.setOrderId(purchaseOciPictureAddVo.getOrderId()); addPurchaseOcrPicture.setOcrStatus(PurchaseConstant.OCR_STATUS[0]); addPurchaseOcrPicture.setCount(purchaseOcrPicture.getCount()); + addPurchaseOcrPicture.setOcrPictureOrder(purchaseOcrPicture.getOcrPictureOrder()); addPurchaseOcrPicture.setParentPicturePath(purchaseOcrPicture.getParentPicturePath()); purchaseOcrPictureAddList.add(addPurchaseOcrPicture); } diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/utils/AliOcrUtil.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/utils/AliOcrUtil.java index ae015ca5..a1abf995 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/utils/AliOcrUtil.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/utils/AliOcrUtil.java @@ -61,11 +61,20 @@ public class AliOcrUtil { public static JSONObject multiRoundConversationCall(PurchaseOcrPicture purchaseOcrPicture, PurchaseOcrExample purchaseOcrExample, ProductService productService, PurchaseDetailService purchaseDetailService) throws ApiException, NoApiKeyException, UploadFileException { final JSONObject jsonObject = new JSONObject(); final String picturePath = purchaseOcrPicture.getOcrPicture(); - final String parentPicturePath = purchaseOcrPicture.getParentPicturePath(); final Integer count = purchaseOcrPicture.getCount(); final String orderId = purchaseOcrPicture.getOrderId(); final String shopId = purchaseOcrPicture.getShopId(); - + // 下角标,第一张那个主图和子图用 前台传的 货号和名称,后边的主图子图那个JSON示例的货号和名称 (先判断前台传值了没) 后边递加1、2、3...... + final String ocrPictureOrder = purchaseOcrPicture.getOcrPictureOrder(); + // 拼接的示例结果 + String productSnExample = purchaseOcrExample.getProductSn(); + String productNameExample = purchaseOcrExample.getProductName(); + if(StringUtils.isNotEmpty(ocrPictureOrder)){ + final String[] strings = ocrPictureOrder.split("-"); + final String indexStr = strings[0]; + productSnExample += indexStr; + productNameExample += indexStr; + } final StopWatch stopWatch = new StopWatch("Ai回答计时"); Constants.apiKey = "sk-bcfa4865b89548acb8225f910f13d682"; final CopyOnWriteArrayList multiModalConversationResults = new CopyOnWriteArrayList<>(); @@ -76,7 +85,7 @@ public class AliOcrUtil { final MultiModalMessageItemImage userImage = new MultiModalMessageItemImage(picturePath); final String firstQuestionMsg = "请把图片中的内容按照商品的不同规格拆分,返回" + count + "条JSON数据。\n" + - " JSON示例:[{ \"productSn\": \"" + purchaseOcrExample.getProductSn() + "\", \"productName\":\"" + purchaseOcrExample.getProductName() + "\", \"price\": \"" + purchaseOcrExample.getPrice() + "\", \"productCount\": \"" + purchaseOcrExample.getProductCount() + "\", \"attributeList\": \"{'color':'" + purchaseOcrExample.getColor() + "','size':'" + purchaseOcrExample.getSize() + "'}\" }]。" + + " JSON示例:[{ \"productSn\": \"" + productSnExample + "\", \"productName\":\"" + productNameExample + "\", \"price\": \"" + purchaseOcrExample.getPrice() + "\", \"productCount\": \"" + purchaseOcrExample.getProductCount() + "\", \"attributeList\": \"{'color':'" + purchaseOcrExample.getColor() + "','size':'" + purchaseOcrExample.getSize() + "'}\" }]。" + "以下是几点要求: " + "1.JSON中“productSn”字段可能由字母或数字或特殊符号组成,“color”字段如果图片中没有内容,则赋值“均色”,“size”字段如果图片中没有内容,则赋值“均码”。" + "2.严格按照JSON示例的格式和字段名返回! " + @@ -85,6 +94,7 @@ public class AliOcrUtil { "5.如果图中内容没有productSn和productName信息,则使用JSON示例中的值填充。 " + "6.请注意返回JSON符号解析格式正确 ,确保java程序能够正确解析。" + "7.严格返回" + count + "条JSON数据,如果数量有偏差按照实际条数返回,不能自动省略!"; + log.info("AI提问内容:"+firstQuestionMsg); MultiModalMessageItemText userText = new MultiModalMessageItemText(firstQuestionMsg); final MultiModalConversationMessage userMessage = MultiModalConversationMessage.builder().role(Role.USER.getValue()) @@ -118,9 +128,9 @@ public class AliOcrUtil { String jsonStr = '[' + text.substring(startIndex, endIndex + 1) + ']'; // 有时候返回的是productCounts,改为productCount jsonStr = fixProductCounts(jsonStr); - JSONArray json = new JSONArray(); + JSONArray endJson = new JSONArray(); try{ - json = JSON.parseArray(jsonStr); + endJson = JSON.parseArray(jsonStr); }catch (Exception e){ log.error(Thread.currentThread().getName()+"-一轮对话--->json识别报错喽,没关系,我把错误信息输出出来:"+e.getMessage(), e); // 如果格式化报错,特殊处理下,再次进行转义。 @@ -134,7 +144,7 @@ public class AliOcrUtil { // 如果是attributeList出现问题,那么尝试修复。 jsonStr = fixAttributeList(jsonStr); try{ - json = JSON.parseArray(jsonStr); + endJson = JSON.parseArray(jsonStr); }catch (Exception replaceOneException){ log.error(Thread.currentThread().getName()+"-一轮对话--->json识别报错喽,没关系,attributeList替换了也没好使!"); needAgain = true; @@ -143,13 +153,13 @@ public class AliOcrUtil { } // 识别多了个“}” - if(message.contains("not close json text")){ + if(message.contains("not close endJson text")){ needAgain = false; log.error(Thread.currentThread().getName()+"-一轮对话--->json识别报错喽,没关系,可能是多了“}”,我来去掉试一下一下!"); // jsonStr = jsonStr.substring(0, jsonStr.length()-1); try{ - json = JSON.parseArray(jsonStr); + endJson = JSON.parseArray(jsonStr); }catch (Exception replaceOneException){ log.error(Thread.currentThread().getName()+"-一轮对话--->json识别报错喽,没关系,可能是多了“}”,去掉了也没好使!"); needAgain = true; @@ -186,7 +196,7 @@ public class AliOcrUtil { try{ // - json = JSON.parseArray(errorJsonJsonStr); + endJson = JSON.parseArray(errorJsonJsonStr); }catch (Exception errorJsonException){ log.error(Thread.currentThread().getName()+"-一轮对话--->json识别报错喽,重新识别又报错了,没关系,我把错误信息输出出来:"+errorJsonException.getMessage(), errorJsonException); // 如果格式化报错,特殊处理下,再次进行转义。 @@ -198,7 +208,7 @@ public class AliOcrUtil { // 如果是attributeList出现问题,那么尝试修复。 errorJsonJsonStr = fixAttributeList(errorJsonJsonStr); try{ - json = JSON.parseArray(errorJsonJsonStr); + endJson = JSON.parseArray(errorJsonJsonStr); }catch (Exception errorJsonJsonException){ log.error(Thread.currentThread().getName()+"-一轮对话--->json识别报错喽,重新识别又报错了,attributeList替换了也没好使!"); firstCheckResult = true; @@ -206,13 +216,13 @@ public class AliOcrUtil { } // 识别多了个“}” - if(errorJsonExceptionMessage.contains("not close json text")){ + if(errorJsonExceptionMessage.contains("not close endJson text")){ firstCheckResult = false; log.error(Thread.currentThread().getName()+"-一轮对话--->json识别报错喽,重新识别又报错了,没关系,可能是多了“}”,我来去掉试一下一下!"); // errorJsonJsonStr = errorJsonJsonStr.substring(0, errorJsonJsonStr.length()-1); try{ - json = JSON.parseArray(errorJsonJsonStr); + endJson = JSON.parseArray(errorJsonJsonStr); }catch (Exception replaceOneException){ log.error(Thread.currentThread().getName()+"-一轮对话--->json识别报错喽,重新识别又报错了,可能是多了“}”,去掉了也没好使!"); firstCheckResult = true; @@ -227,7 +237,7 @@ public class AliOcrUtil { } } - final int fristResultCount = json.size(); + final int fristResultCount = endJson.size(); // 我会在这里对结果进行解析,然后,判断要不要走第二次回话 final int missingCount = count - fristResultCount; if (missingCount > 0) { @@ -259,7 +269,12 @@ public class AliOcrUtil { // 有时候返回的是productCounts,改为productCount secondJsonStr = fixProductCounts(secondJsonStr); try{ - json = JSON.parseArray(secondJsonStr); + final JSONArray secondJson = JSON.parseArray(secondJsonStr); + final int secondResultCount = secondJson.size(); + // 20240515 跟第一次的数据对比,哪个数量多,用哪个。 + if(secondResultCount > fristResultCount){ + endJson = secondJson; + } }catch (Exception e){ boolean needAgain = true; log.error(Thread.currentThread().getName()+"-二轮对话--->json识别报错喽,没关系,我把错误信息输出出来:"+e.getMessage(),e); @@ -271,20 +286,32 @@ public class AliOcrUtil { // 如果是attributeList出现问题,那么尝试修复。 secondJsonStr = fixAttributeList(secondJsonStr); try{ - json = JSON.parseArray(secondJsonStr); + // endJson = JSON.parseArray(secondJsonStr); + final JSONArray secondJson = JSON.parseArray(secondJsonStr); + final int secondResultCount = secondJson.size(); + // 20240515 跟第一次的数据对比,哪个数量多,用哪个。 + if(secondResultCount > fristResultCount){ + endJson = secondJson; + } }catch (Exception exception){ log.error(Thread.currentThread().getName()+"-二轮对话--->json识别报错喽,attributeList替换了也没好使!"); needAgain = true; } } // 识别多了个“}” - if(message.contains("not close json text")){ + if(message.contains("not close endJson text")){ needAgain = false; log.error(Thread.currentThread().getName()+"-二轮对话--->json识别报错喽,没关系,可能是多了“}”,我来去掉试一下一下!"); // secondJsonStr = secondJsonStr.substring(0, secondJsonStr.length()-1); try{ - json = JSON.parseArray(secondJsonStr); + // endJson = JSON.parseArray(secondJsonStr); + final JSONArray secondJson = JSON.parseArray(secondJsonStr); + final int secondResultCount = secondJson.size(); + // 20240515 跟第一次的数据对比,哪个数量多,用哪个。 + if(secondResultCount > fristResultCount){ + endJson = secondJson; + } }catch (Exception replaceOneException){ log.error(Thread.currentThread().getName()+"-二轮对话--->json识别报错喽,可能是多了“}”,去掉了也没好使!"); needAgain = true; @@ -320,7 +347,13 @@ public class AliOcrUtil { errorJsonJsonStr = fixProductCounts(errorJsonJsonStr); try{ // - json = JSON.parseArray(errorJsonJsonStr); + // endJson = JSON.parseArray(errorJsonJsonStr); + final JSONArray secondJson = JSON.parseArray(errorJsonJsonStr); + final int secondResultCount = secondJson.size(); + // 20240515 跟第一次的数据对比,哪个数量多,用哪个。 + if(secondResultCount > fristResultCount){ + endJson = secondJson; + } }catch (Exception errorJsonException){ boolean secondCheckResult = true; final String errorJsonExceptionMessage = errorJsonException.getMessage(); @@ -329,21 +362,33 @@ public class AliOcrUtil { secondCheckResult = false; log.error(Thread.currentThread().getName()+"-二轮对话--->json识别报错喽,,重新识别又报错了,没关系,,attributeList格式有问题,我来替换一下!"); // 如果是attributeList出现问题,那么尝试修复。 - secondJsonStr = fixAttributeList(secondJsonStr); + errorJsonJsonStr = fixAttributeList(errorJsonJsonStr); try{ - json = JSON.parseArray(secondJsonStr); + // endJson = JSON.parseArray(errorJsonJsonStr); + final JSONArray secondJson = JSON.parseArray(errorJsonJsonStr); + final int secondResultCount = secondJson.size(); + // 20240515 跟第一次的数据对比,哪个数量多,用哪个。 + if(secondResultCount > fristResultCount){ + endJson = secondJson; + } }catch (Exception secondCheckException){ log.error(Thread.currentThread().getName()+"-二轮对话--->json识别报错喽,,重新识别又报错了,attributeList替换了也没好使!"); secondCheckResult = true; } } - if(errorJsonExceptionMessage.contains("not close json text")){ + if(errorJsonExceptionMessage.contains("not close endJson text")){ secondCheckResult = false; log.error(Thread.currentThread().getName()+"-二轮对话--->json识别报错喽,重新识别又报错了,没关系,可能是多了“}”,我来去掉试一下一下!"); // 如果是attributeList出现问题,那么尝试修复。 - secondJsonStr = secondJsonStr.substring(0, secondJsonStr.length()-1); + errorJsonJsonStr = errorJsonJsonStr.substring(0, errorJsonJsonStr.length()-1); try{ - json = JSON.parseArray(secondJsonStr); + // endJson = JSON.parseArray(errorJsonJsonStr); + final JSONArray secondJson = JSON.parseArray(errorJsonJsonStr); + final int secondResultCount = secondJson.size(); + // 20240515 跟第一次的数据对比,哪个数量多,用哪个。 + if(secondResultCount > fristResultCount){ + endJson = secondJson; + } }catch (Exception secondCheckException){ log.error(Thread.currentThread().getName()+"-二轮对话--->json识别报错喽,重新识别又报错了,可能是多了“}”,去掉了也没好使!"); secondCheckResult = true; @@ -351,22 +396,21 @@ public class AliOcrUtil { } if(secondCheckResult){ - log.error(Thread.currentThread().getName()+"-二轮对话--->json识别报错喽,,重新识别又报错了,不识别了,直接毁灭吧!"); - throw errorJsonException; + log.error(Thread.currentThread().getName()+"-二轮对话--->json识别报错喽,,重新识别又报错了,不识别了,直接用第一次识别的结果吧!"); } } } } } } - log.info(JSON.toJSONString(json)); + log.info(JSON.toJSONString(endJson)); stopWatch.start("解析结果=="); // 解析结果 // 入库的时候子图直接存放主图的路径 /*if (StringUtils.isNotEmpty(parentPicturePath)) { picturePath = parentPicturePath; }*/ - getPurchaseDetailMap(purchaseDetailService, productService, orderId, shopId, picturePath, json); + getPurchaseDetailMap(purchaseDetailService, productService, orderId, shopId, picturePath, endJson); stopWatch.stop(); // 将map 转为list 进行落库操作 /*stopWatch.start("批量插入=="); @@ -375,11 +419,11 @@ public class AliOcrUtil { stopWatch.stop();*/ log.info(stopWatch.prettyPrint()); - jsonObject.put("resultContent", json); + jsonObject.put("resultContent", endJson); jsonObject.put("tokenCount", result.getUsage()); jsonObject.put("requestId", result.getRequestId()); jsonObject.put("cod", 200); - jsonObject.put("ocrCount", json.size()); + jsonObject.put("ocrCount", endJson.size()); return jsonObject; } @@ -636,12 +680,12 @@ public class AliOcrUtil { productSnMap.put(product.getProductSn(), product); }); // 根据商品名称获取商品信息 - final CopyOnWriteArrayList productByProductNameList = productService.getProductByProductNameList(productNameList, shopId); + /*final CopyOnWriteArrayList productByProductNameList = productService.getProductByProductNameList(productNameList, shopId); final Map productNameMap = new ConcurrentHashMap<>(); // 将商品信息封装到Map 中,商品名称作为key,商品作为value productByProductNameList.forEach(product -> { productNameMap.put(product.getProductName(), product); - }); + });*/ // 得到数据之后,开始跟该店铺的商品进行对比。 // orderId final Map purchaseDetailMap = new ConcurrentHashMap<>(); @@ -652,13 +696,13 @@ public class AliOcrUtil { // 根据商品的货号或者 Product product = productSnMap.get(productSn); // 如果货号存在,就以货号为准查询库存商品能查到就是有,没有查到就是没有,如果有货号,不再根据名称查询 - if (product == null && StringUtils.isEmpty(productSn)) { + /*if (product == null && StringUtils.isEmpty(productSn)) { product = productNameMap.get(productName); if (product != null) { // 如果根据名称获取到商品信息,则需要重新赋值货号,保持统一 productSn = product.getProductSn(); } - } + }*/ // 先将规格信息拼接好,后边肯定会插入这个值 final CopyOnWriteArrayList attributeList = purchaseOcrVo.getAttributeList(); final StringBuilder attributeStr = new StringBuilder(); diff --git a/hiver-modules/hiver-mall/src/main/resources/mapper/PurchaseOcrPictureMapper.xml b/hiver-modules/hiver-mall/src/main/resources/mapper/PurchaseOcrPictureMapper.xml index 677d4af1..00be553e 100644 --- a/hiver-modules/hiver-mall/src/main/resources/mapper/PurchaseOcrPictureMapper.xml +++ b/hiver-modules/hiver-mall/src/main/resources/mapper/PurchaseOcrPictureMapper.xml @@ -11,7 +11,7 @@ - + @@ -94,7 +94,7 @@ ocr_picture_order, ocr_status, ocr_msg, shop_id, shop_name,count,ocr_count,paren #{purchaseOcrPicture.createByName,jdbcType=VARCHAR},#{purchaseOcrPicture.createTime,jdbcType=TIMESTAMP}, #{purchaseOcrPicture.delFlag,jdbcType=INTEGER},#{purchaseOcrPicture.updateBy,jdbcType=VARCHAR}, #{purchaseOcrPicture.updateTime,jdbcType=TIMESTAMP},#{purchaseOcrPicture.orderId,jdbcType=VARCHAR}, - #{purchaseOcrPicture.ocrPicture,jdbcType=VARCHAR},#{purchaseOcrPicture.ocrPictureOrder,jdbcType=INTEGER}, + #{purchaseOcrPicture.ocrPicture,jdbcType=VARCHAR},#{purchaseOcrPicture.ocrPictureOrder,jdbcType=VARCHAR}, #{purchaseOcrPicture.ocrStatus,jdbcType=INTEGER},#{purchaseOcrPicture.ocrMsg,jdbcType=VARCHAR}, #{purchaseOcrPicture.shopId,jdbcType=VARCHAR},#{purchaseOcrPicture.shopName,jdbcType=VARCHAR}, #{purchaseOcrPicture.count,jdbcType=INTEGER},#{purchaseOcrPicture.ocrCount,jdbcType=INTEGER},#{purchaseOcrPicture.parentPicturePath,jdbcType=VARCHAR})