|
|
|
@ -1,6 +1,7 @@ |
|
|
|
package cc.hiver.mall.utils;// Copyright (c) Alibaba, Inc. and its affiliates.
|
|
|
|
|
|
|
|
import cc.hiver.core.common.constant.CommonConstant; |
|
|
|
import cc.hiver.core.common.utils.CommonUtil; |
|
|
|
import cc.hiver.mall.config.aliocr.AliOcrConfig; |
|
|
|
import cc.hiver.mall.entity.*; |
|
|
|
import cc.hiver.mall.pojo.vo.*; |
|
|
|
@ -59,7 +60,7 @@ public class AliOcrUtil { |
|
|
|
* @author 王富康 |
|
|
|
* @date 2024/3/31 |
|
|
|
*/ |
|
|
|
public static JSONObject multiRoundConversationCall(PurchaseOcrPicture purchaseOcrPicture, PurchaseOcrExample purchaseOcrExample, ProductService productService, PurchaseDetailService purchaseDetailService) throws ApiException, NoApiKeyException, UploadFileException { |
|
|
|
public static JSONObject multiRoundConversationCall(PurchaseOcrPicture purchaseOcrPicture, PurchaseOcrExample purchaseOcrExample, ProductService productService, PurchaseDetailService purchaseDetailService, ProductCategoryService productCategoryService) throws ApiException, NoApiKeyException, UploadFileException { |
|
|
|
final JSONObject jsonObject = new JSONObject(); |
|
|
|
final String ocrPictureId = purchaseOcrPicture.getId(); |
|
|
|
final String picturePath = purchaseOcrPicture.getOcrPicture(); |
|
|
|
@ -71,13 +72,13 @@ public class AliOcrUtil { |
|
|
|
// 拼接的示例结果
|
|
|
|
String productSnExample = purchaseOcrExample.getProductSn(); |
|
|
|
String productNameExample = purchaseOcrExample.getProductName(); |
|
|
|
if(StringUtils.isNotEmpty(ocrPictureOrder)){ |
|
|
|
if (StringUtils.isNotEmpty(ocrPictureOrder)) { |
|
|
|
final String[] strings = ocrPictureOrder.split("-"); |
|
|
|
final String indexStr = strings[0]; |
|
|
|
productSnExample += indexStr; |
|
|
|
productNameExample += indexStr; |
|
|
|
} |
|
|
|
final StopWatch stopWatch = new StopWatch(ocrPictureId+"Ai回答计时"); |
|
|
|
final StopWatch stopWatch = new StopWatch(ocrPictureId + "Ai回答计时"); |
|
|
|
Constants.apiKey = "sk-bcfa4865b89548acb8225f910f13d682"; |
|
|
|
final CopyOnWriteArrayList<MultiModalConversationResult> multiModalConversationResults = new CopyOnWriteArrayList<>(); |
|
|
|
final MultiModalConversation conv = new MultiModalConversation(); |
|
|
|
@ -96,7 +97,7 @@ public class AliOcrUtil { |
|
|
|
"5.如果按照你的理解在图中找到了productSn和productName字段对应的信息,则productSn和productName字段的值以图中内容为准。如果按照你的理解在图中没有找到productSn和productName字段对应的信息,则productSn和productName字段的值使用JSON示例中productSn和productName的值填充。 " + |
|
|
|
"6.请注意返回JSON符号解析格式正确 ,确保java程序能够正确解析。" + |
|
|
|
"7.严格返回" + count + "条JSON数据,如果数量有偏差按照实际条数返回,不能自动省略!"; |
|
|
|
log.info("AI提问内容:"+firstQuestionMsg); |
|
|
|
log.info("AI提问内容:" + firstQuestionMsg); |
|
|
|
MultiModalMessageItemText userText = new MultiModalMessageItemText(firstQuestionMsg); |
|
|
|
final MultiModalConversationMessage userMessage = |
|
|
|
MultiModalConversationMessage.builder().role(Role.USER.getValue()) |
|
|
|
@ -114,7 +115,7 @@ public class AliOcrUtil { |
|
|
|
multiModalConversationResults.add(result); |
|
|
|
// 解析结果
|
|
|
|
String text = result.getOutput().getChoices().get(0).getMessage().getContent().get(0).get("text").toString(); |
|
|
|
log.info("一轮对话-的json======"+ text); |
|
|
|
log.info("一轮对话-的json======" + text); |
|
|
|
// 根据{}截取数据
|
|
|
|
final int startIndex = text.indexOf('{'); |
|
|
|
final int endIndex = text.lastIndexOf('}'); |
|
|
|
@ -127,45 +128,45 @@ public class AliOcrUtil { |
|
|
|
// 有时候返回的是productCounts,改为productCount
|
|
|
|
jsonStr = fixJsonStr(jsonStr); |
|
|
|
JSONArray endJson = new JSONArray(); |
|
|
|
try{ |
|
|
|
try { |
|
|
|
endJson = JSON.parseArray(jsonStr); |
|
|
|
}catch (Exception e){ |
|
|
|
log.error(Thread.currentThread().getName()+"-一轮对话--->json识别报错喽,没关系,我把错误信息输出出来:"+e.getMessage(), e); |
|
|
|
} catch (Exception e) { |
|
|
|
log.error(Thread.currentThread().getName() + "-一轮对话--->json识别报错喽,没关系,我把错误信息输出出来:" + e.getMessage(), e); |
|
|
|
// 如果格式化报错,特殊处理下,再次进行转义。
|
|
|
|
final String message = e.getMessage(); |
|
|
|
boolean needAgain = true; |
|
|
|
// 以下是对目前可能出现的问题进行过滤处理
|
|
|
|
// attributeList格式不对
|
|
|
|
if(message.contains("attributeList")){ |
|
|
|
if (message.contains("attributeList")) { |
|
|
|
needAgain = false; |
|
|
|
log.error(Thread.currentThread().getName()+"-一轮对话--->json识别报错喽,没关系,attributeList格式有问题,我来替换一下!"); |
|
|
|
log.error(Thread.currentThread().getName() + "-一轮对话--->json识别报错喽,没关系,attributeList格式有问题,我来替换一下!"); |
|
|
|
// 如果是attributeList出现问题,那么尝试修复。
|
|
|
|
jsonStr = fixAttributeList(jsonStr); |
|
|
|
try{ |
|
|
|
try { |
|
|
|
endJson = JSON.parseArray(jsonStr); |
|
|
|
}catch (Exception replaceOneException){ |
|
|
|
log.error(Thread.currentThread().getName()+"-一轮对话--->json识别报错喽,没关系,attributeList替换了也没好使!"); |
|
|
|
} catch (Exception replaceOneException) { |
|
|
|
log.error(Thread.currentThread().getName() + "-一轮对话--->json识别报错喽,没关系,attributeList替换了也没好使!"); |
|
|
|
needAgain = true; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
// 识别多了个“}”
|
|
|
|
if(message.contains("not close endJson text")){ |
|
|
|
if (message.contains("not close endJson text")) { |
|
|
|
needAgain = false; |
|
|
|
log.error(Thread.currentThread().getName()+"-一轮对话--->json识别报错喽,没关系,可能是多了“}”,我来去掉试一下一下!"); |
|
|
|
log.error(Thread.currentThread().getName() + "-一轮对话--->json识别报错喽,没关系,可能是多了“}”,我来去掉试一下一下!"); |
|
|
|
//
|
|
|
|
jsonStr = jsonStr.substring(0, jsonStr.length()-1); |
|
|
|
try{ |
|
|
|
jsonStr = jsonStr.substring(0, jsonStr.length() - 1); |
|
|
|
try { |
|
|
|
endJson = JSON.parseArray(jsonStr); |
|
|
|
}catch (Exception replaceOneException){ |
|
|
|
log.error(Thread.currentThread().getName()+"-一轮对话--->json识别报错喽,没关系,可能是多了“}”,去掉了也没好使!"); |
|
|
|
} catch (Exception replaceOneException) { |
|
|
|
log.error(Thread.currentThread().getName() + "-一轮对话--->json识别报错喽,没关系,可能是多了“}”,去掉了也没好使!"); |
|
|
|
needAgain = true; |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
if(needAgain){ |
|
|
|
log.error(Thread.currentThread().getName()+"-一轮对话--->json识别报错喽,没关系,我来重新识别一下!"); |
|
|
|
if (needAgain) { |
|
|
|
log.error(Thread.currentThread().getName() + "-一轮对话--->json识别报错喽,没关系,我来重新识别一下!"); |
|
|
|
//尝试重新识别一次
|
|
|
|
final String errorJsonQuestionMsg = "返回的json格式有误,请重新返回。"; |
|
|
|
final MultiModalMessageItemText assistentText = new MultiModalMessageItemText( |
|
|
|
@ -183,7 +184,7 @@ public class AliOcrUtil { |
|
|
|
stopWatch.stop(); |
|
|
|
// 解析结果
|
|
|
|
text = result.getOutput().getChoices().get(0).getMessage().getContent().get(0).get("text").toString(); |
|
|
|
log.info("一轮对话--json格式错误,重新识别的结果======"+ text); |
|
|
|
log.info("一轮对话--json格式错误,重新识别的结果======" + text); |
|
|
|
// 根据{}截取数据
|
|
|
|
final int secondStartIndex = text.indexOf('{'); |
|
|
|
final int secondEndIndex = text.lastIndexOf('}'); |
|
|
|
@ -192,43 +193,43 @@ public class AliOcrUtil { |
|
|
|
// 有时候返回的是productCounts,改为productCount
|
|
|
|
errorJsonJsonStr = fixJsonStr(errorJsonJsonStr); |
|
|
|
|
|
|
|
try{ |
|
|
|
try { |
|
|
|
//
|
|
|
|
endJson = JSON.parseArray(errorJsonJsonStr); |
|
|
|
}catch (Exception errorJsonException){ |
|
|
|
log.error(Thread.currentThread().getName()+"-一轮对话--->json识别报错喽,重新识别又报错了,没关系,我把错误信息输出出来:"+errorJsonException.getMessage(), errorJsonException); |
|
|
|
} catch (Exception errorJsonException) { |
|
|
|
log.error(Thread.currentThread().getName() + "-一轮对话--->json识别报错喽,重新识别又报错了,没关系,我把错误信息输出出来:" + errorJsonException.getMessage(), errorJsonException); |
|
|
|
// 如果格式化报错,特殊处理下,再次进行转义。
|
|
|
|
final String errorJsonExceptionMessage = errorJsonException.getMessage(); |
|
|
|
boolean firstCheckResult = true; |
|
|
|
if(errorJsonExceptionMessage.contains("attributeList")){ |
|
|
|
if (errorJsonExceptionMessage.contains("attributeList")) { |
|
|
|
firstCheckResult = false; |
|
|
|
log.error(Thread.currentThread().getName()+"-一轮对话--->json识别报错喽,重新识别又报错了,没关系,attributeList格式有问题,我来替换一下!"); |
|
|
|
log.error(Thread.currentThread().getName() + "-一轮对话--->json识别报错喽,重新识别又报错了,没关系,attributeList格式有问题,我来替换一下!"); |
|
|
|
// 如果是attributeList出现问题,那么尝试修复。
|
|
|
|
errorJsonJsonStr = fixAttributeList(errorJsonJsonStr); |
|
|
|
try{ |
|
|
|
try { |
|
|
|
endJson = JSON.parseArray(errorJsonJsonStr); |
|
|
|
}catch (Exception errorJsonJsonException){ |
|
|
|
log.error(Thread.currentThread().getName()+"-一轮对话--->json识别报错喽,重新识别又报错了,attributeList替换了也没好使!"); |
|
|
|
} catch (Exception errorJsonJsonException) { |
|
|
|
log.error(Thread.currentThread().getName() + "-一轮对话--->json识别报错喽,重新识别又报错了,attributeList替换了也没好使!"); |
|
|
|
firstCheckResult = true; |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
// 识别多了个“}”
|
|
|
|
if(errorJsonExceptionMessage.contains("not close endJson text")){ |
|
|
|
if (errorJsonExceptionMessage.contains("not close endJson text")) { |
|
|
|
firstCheckResult = false; |
|
|
|
log.error(Thread.currentThread().getName()+"-一轮对话--->json识别报错喽,重新识别又报错了,没关系,可能是多了“}”,我来去掉试一下一下!"); |
|
|
|
log.error(Thread.currentThread().getName() + "-一轮对话--->json识别报错喽,重新识别又报错了,没关系,可能是多了“}”,我来去掉试一下一下!"); |
|
|
|
//
|
|
|
|
errorJsonJsonStr = errorJsonJsonStr.substring(0, errorJsonJsonStr.length()-1); |
|
|
|
try{ |
|
|
|
errorJsonJsonStr = errorJsonJsonStr.substring(0, errorJsonJsonStr.length() - 1); |
|
|
|
try { |
|
|
|
endJson = JSON.parseArray(errorJsonJsonStr); |
|
|
|
}catch (Exception replaceOneException){ |
|
|
|
log.error(Thread.currentThread().getName()+"-一轮对话--->json识别报错喽,重新识别又报错了,可能是多了“}”,去掉了也没好使!"); |
|
|
|
} catch (Exception replaceOneException) { |
|
|
|
log.error(Thread.currentThread().getName() + "-一轮对话--->json识别报错喽,重新识别又报错了,可能是多了“}”,去掉了也没好使!"); |
|
|
|
firstCheckResult = true; |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
if(firstCheckResult){ |
|
|
|
log.error(Thread.currentThread().getName()+"-一轮对话--->json识别报错喽,,重新识别又报错了,不识别了,直接毁灭吧!"); |
|
|
|
if (firstCheckResult) { |
|
|
|
log.error(Thread.currentThread().getName() + "-一轮对话--->json识别报错喽,,重新识别又报错了,不识别了,直接毁灭吧!"); |
|
|
|
throw errorJsonException; |
|
|
|
} |
|
|
|
} |
|
|
|
@ -255,69 +256,69 @@ public class AliOcrUtil { |
|
|
|
stopWatch.stop(); |
|
|
|
// 解析结果
|
|
|
|
String secondText = result.getOutput().getChoices().get(0).getMessage().getContent().get(0).get("text").toString(); |
|
|
|
log.info("二轮对话识别结果:"+secondText); |
|
|
|
log.info("二轮对话识别结果:" + secondText); |
|
|
|
// 根据{}截取数据
|
|
|
|
final int secondStartIndex = secondText.indexOf('{'); |
|
|
|
final int secondEndIndex = secondText.lastIndexOf('}'); |
|
|
|
if (secondStartIndex == -1 || secondEndIndex == -1) { |
|
|
|
// 二轮对话,没有查询到想要的数据,那么就使用一轮的结果
|
|
|
|
log.info(Thread.currentThread().getName()+"-二轮对话--->识别数据失败,使用第一次的识别结果未找到指定标识符:识别结果为:" + text); |
|
|
|
}else{ |
|
|
|
log.info(Thread.currentThread().getName() + "-二轮对话--->识别数据失败,使用第一次的识别结果未找到指定标识符:识别结果为:" + text); |
|
|
|
} else { |
|
|
|
String secondJsonStr = '[' + secondText.substring(secondStartIndex, secondEndIndex + 1) + ']'; |
|
|
|
// 有时候返回的是productCounts,改为productCount
|
|
|
|
secondJsonStr = fixJsonStr(secondJsonStr); |
|
|
|
try{ |
|
|
|
try { |
|
|
|
final JSONArray secondJson = JSON.parseArray(secondJsonStr); |
|
|
|
final int secondResultCount = secondJson.size(); |
|
|
|
// 20240515 跟第一次的数据对比,哪个数量多,用哪个。
|
|
|
|
if(secondResultCount > fristResultCount){ |
|
|
|
if (secondResultCount > fristResultCount) { |
|
|
|
endJson = secondJson; |
|
|
|
} |
|
|
|
}catch (Exception e){ |
|
|
|
} catch (Exception e) { |
|
|
|
boolean needAgain = true; |
|
|
|
log.error(Thread.currentThread().getName()+"-二轮对话--->json识别报错喽,没关系,我把错误信息输出出来:"+e.getMessage(),e); |
|
|
|
log.error(Thread.currentThread().getName() + "-二轮对话--->json识别报错喽,没关系,我把错误信息输出出来:" + e.getMessage(), e); |
|
|
|
// 如果格式化报错,特殊处理下,再次进行转义。
|
|
|
|
final String message = e.getMessage(); |
|
|
|
if(message.contains("attributeList")){ |
|
|
|
if (message.contains("attributeList")) { |
|
|
|
needAgain = false; |
|
|
|
log.error(Thread.currentThread().getName()+"-二轮对话--->json识别报错喽,没关系,attributeList格式有问题,我来替换一下!"); |
|
|
|
log.error(Thread.currentThread().getName() + "-二轮对话--->json识别报错喽,没关系,attributeList格式有问题,我来替换一下!"); |
|
|
|
// 如果是attributeList出现问题,那么尝试修复。
|
|
|
|
secondJsonStr = fixAttributeList(secondJsonStr); |
|
|
|
try{ |
|
|
|
try { |
|
|
|
// endJson = JSON.parseArray(secondJsonStr);
|
|
|
|
final JSONArray secondJson = JSON.parseArray(secondJsonStr); |
|
|
|
final int secondResultCount = secondJson.size(); |
|
|
|
// 20240515 跟第一次的数据对比,哪个数量多,用哪个。
|
|
|
|
if(secondResultCount > fristResultCount){ |
|
|
|
if (secondResultCount > fristResultCount) { |
|
|
|
endJson = secondJson; |
|
|
|
} |
|
|
|
}catch (Exception exception){ |
|
|
|
log.error(Thread.currentThread().getName()+"-二轮对话--->json识别报错喽,attributeList替换了也没好使!"); |
|
|
|
} catch (Exception exception) { |
|
|
|
log.error(Thread.currentThread().getName() + "-二轮对话--->json识别报错喽,attributeList替换了也没好使!"); |
|
|
|
needAgain = true; |
|
|
|
} |
|
|
|
} |
|
|
|
// 识别多了个“}”
|
|
|
|
if(message.contains("not close endJson text")){ |
|
|
|
if (message.contains("not close endJson text")) { |
|
|
|
needAgain = false; |
|
|
|
log.error(Thread.currentThread().getName()+"-二轮对话--->json识别报错喽,没关系,可能是多了“}”,我来去掉试一下一下!"); |
|
|
|
log.error(Thread.currentThread().getName() + "-二轮对话--->json识别报错喽,没关系,可能是多了“}”,我来去掉试一下一下!"); |
|
|
|
//
|
|
|
|
secondJsonStr = secondJsonStr.substring(0, secondJsonStr.length()-1); |
|
|
|
try{ |
|
|
|
secondJsonStr = secondJsonStr.substring(0, secondJsonStr.length() - 1); |
|
|
|
try { |
|
|
|
// endJson = JSON.parseArray(secondJsonStr);
|
|
|
|
final JSONArray secondJson = JSON.parseArray(secondJsonStr); |
|
|
|
final int secondResultCount = secondJson.size(); |
|
|
|
// 20240515 跟第一次的数据对比,哪个数量多,用哪个。
|
|
|
|
if(secondResultCount > fristResultCount){ |
|
|
|
if (secondResultCount > fristResultCount) { |
|
|
|
endJson = secondJson; |
|
|
|
} |
|
|
|
}catch (Exception replaceOneException){ |
|
|
|
log.error(Thread.currentThread().getName()+"-二轮对话--->json识别报错喽,可能是多了“}”,去掉了也没好使!"); |
|
|
|
} catch (Exception replaceOneException) { |
|
|
|
log.error(Thread.currentThread().getName() + "-二轮对话--->json识别报错喽,可能是多了“}”,去掉了也没好使!"); |
|
|
|
needAgain = true; |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
if(needAgain){ |
|
|
|
log.error(Thread.currentThread().getName()+"-二轮对话--->json识别报错喽,没关系,我来重新识别一下!"); |
|
|
|
if (needAgain) { |
|
|
|
log.error(Thread.currentThread().getName() + "-二轮对话--->json识别报错喽,没关系,我来重新识别一下!"); |
|
|
|
//尝试重新识别一次
|
|
|
|
final String errorJsonQuestionMsg = "返回的json格式有误,请重新返回。"; |
|
|
|
final MultiModalMessageItemText secondJsonErrorAssistentText = new MultiModalMessageItemText( |
|
|
|
@ -335,7 +336,7 @@ public class AliOcrUtil { |
|
|
|
stopWatch.stop(); |
|
|
|
// 解析结果
|
|
|
|
secondText = result.getOutput().getChoices().get(0).getMessage().getContent().get(0).get("text").toString(); |
|
|
|
log.info("二轮对话-json格式错误,重新识别的结果======"+ secondText); |
|
|
|
log.info("二轮对话-json格式错误,重新识别的结果======" + secondText); |
|
|
|
// 根据{}截取数据
|
|
|
|
final int errorSsecondStartIndex = secondText.indexOf('{'); |
|
|
|
final int errorSecondEndIndex = secondText.lastIndexOf('}'); |
|
|
|
@ -343,58 +344,58 @@ public class AliOcrUtil { |
|
|
|
String errorJsonJsonStr = '[' + secondText.substring(errorSsecondStartIndex, errorSecondEndIndex + 1) + ']'; |
|
|
|
// 有时候返回的是productCounts,改为productCount
|
|
|
|
errorJsonJsonStr = fixJsonStr(errorJsonJsonStr); |
|
|
|
try{ |
|
|
|
try { |
|
|
|
//
|
|
|
|
// endJson = JSON.parseArray(errorJsonJsonStr);
|
|
|
|
final JSONArray secondJson = JSON.parseArray(errorJsonJsonStr); |
|
|
|
final int secondResultCount = secondJson.size(); |
|
|
|
// 20240515 跟第一次的数据对比,哪个数量多,用哪个。
|
|
|
|
if(secondResultCount > fristResultCount){ |
|
|
|
if (secondResultCount > fristResultCount) { |
|
|
|
endJson = secondJson; |
|
|
|
} |
|
|
|
}catch (Exception errorJsonException){ |
|
|
|
} catch (Exception errorJsonException) { |
|
|
|
boolean secondCheckResult = true; |
|
|
|
final String errorJsonExceptionMessage = errorJsonException.getMessage(); |
|
|
|
log.error(Thread.currentThread().getName()+"-二轮对话--->json识别报错喽,重新识别又报错了,没关系,我把错误信息输出出来:"+ errorJsonExceptionMessage, errorJsonException); |
|
|
|
if(errorJsonExceptionMessage.contains("attributeList")){ |
|
|
|
log.error(Thread.currentThread().getName() + "-二轮对话--->json识别报错喽,重新识别又报错了,没关系,我把错误信息输出出来:" + errorJsonExceptionMessage, errorJsonException); |
|
|
|
if (errorJsonExceptionMessage.contains("attributeList")) { |
|
|
|
secondCheckResult = false; |
|
|
|
log.error(Thread.currentThread().getName()+"-二轮对话--->json识别报错喽,,重新识别又报错了,没关系,,attributeList格式有问题,我来替换一下!"); |
|
|
|
log.error(Thread.currentThread().getName() + "-二轮对话--->json识别报错喽,,重新识别又报错了,没关系,,attributeList格式有问题,我来替换一下!"); |
|
|
|
// 如果是attributeList出现问题,那么尝试修复。
|
|
|
|
errorJsonJsonStr = fixAttributeList(errorJsonJsonStr); |
|
|
|
try{ |
|
|
|
try { |
|
|
|
// endJson = JSON.parseArray(errorJsonJsonStr);
|
|
|
|
final JSONArray secondJson = JSON.parseArray(errorJsonJsonStr); |
|
|
|
final int secondResultCount = secondJson.size(); |
|
|
|
// 20240515 跟第一次的数据对比,哪个数量多,用哪个。
|
|
|
|
if(secondResultCount > fristResultCount){ |
|
|
|
if (secondResultCount > fristResultCount) { |
|
|
|
endJson = secondJson; |
|
|
|
} |
|
|
|
}catch (Exception secondCheckException){ |
|
|
|
log.error(Thread.currentThread().getName()+"-二轮对话--->json识别报错喽,,重新识别又报错了,attributeList替换了也没好使!"); |
|
|
|
} catch (Exception secondCheckException) { |
|
|
|
log.error(Thread.currentThread().getName() + "-二轮对话--->json识别报错喽,,重新识别又报错了,attributeList替换了也没好使!"); |
|
|
|
secondCheckResult = true; |
|
|
|
} |
|
|
|
} |
|
|
|
if(errorJsonExceptionMessage.contains("not close endJson text")){ |
|
|
|
if (errorJsonExceptionMessage.contains("not close endJson text")) { |
|
|
|
secondCheckResult = false; |
|
|
|
log.error(Thread.currentThread().getName()+"-二轮对话--->json识别报错喽,重新识别又报错了,没关系,可能是多了“}”,我来去掉试一下一下!"); |
|
|
|
log.error(Thread.currentThread().getName() + "-二轮对话--->json识别报错喽,重新识别又报错了,没关系,可能是多了“}”,我来去掉试一下一下!"); |
|
|
|
// 如果是attributeList出现问题,那么尝试修复。
|
|
|
|
errorJsonJsonStr = errorJsonJsonStr.substring(0, errorJsonJsonStr.length()-1); |
|
|
|
try{ |
|
|
|
errorJsonJsonStr = errorJsonJsonStr.substring(0, errorJsonJsonStr.length() - 1); |
|
|
|
try { |
|
|
|
// endJson = JSON.parseArray(errorJsonJsonStr);
|
|
|
|
final JSONArray secondJson = JSON.parseArray(errorJsonJsonStr); |
|
|
|
final int secondResultCount = secondJson.size(); |
|
|
|
// 20240515 跟第一次的数据对比,哪个数量多,用哪个。
|
|
|
|
if(secondResultCount > fristResultCount){ |
|
|
|
if (secondResultCount > fristResultCount) { |
|
|
|
endJson = secondJson; |
|
|
|
} |
|
|
|
}catch (Exception secondCheckException){ |
|
|
|
log.error(Thread.currentThread().getName()+"-二轮对话--->json识别报错喽,重新识别又报错了,可能是多了“}”,去掉了也没好使!"); |
|
|
|
} catch (Exception secondCheckException) { |
|
|
|
log.error(Thread.currentThread().getName() + "-二轮对话--->json识别报错喽,重新识别又报错了,可能是多了“}”,去掉了也没好使!"); |
|
|
|
secondCheckResult = true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if(secondCheckResult){ |
|
|
|
log.error(Thread.currentThread().getName()+"-二轮对话--->json识别报错喽,,重新识别又报错了,不识别了,直接用第一次识别的结果吧!"); |
|
|
|
if (secondCheckResult) { |
|
|
|
log.error(Thread.currentThread().getName() + "-二轮对话--->json识别报错喽,,重新识别又报错了,不识别了,直接用第一次识别的结果吧!"); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
@ -408,7 +409,7 @@ public class AliOcrUtil { |
|
|
|
/*if (StringUtils.isNotEmpty(parentPicturePath)) { |
|
|
|
picturePath = parentPicturePath; |
|
|
|
}*/ |
|
|
|
getPurchaseDetailMap(purchaseDetailService, productService, orderId, shopId, picturePath, endJson); |
|
|
|
getPurchaseDetailMap(purchaseDetailService, productService, orderId, shopId, picturePath, endJson, productCategoryService); |
|
|
|
stopWatch.stop(); |
|
|
|
// 将map 转为list 进行落库操作
|
|
|
|
/*stopWatch.start("批量插入=="); |
|
|
|
@ -446,7 +447,7 @@ public class AliOcrUtil { |
|
|
|
attributeList = attributeList.replace("productCounts", "productCount"); |
|
|
|
return attributeList; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* 1.有时候返回的是productCounts,改为productCount |
|
|
|
* 2. 有的时候中间会有...,需要特殊处理一下 |
|
|
|
@ -458,16 +459,16 @@ public class AliOcrUtil { |
|
|
|
*/ |
|
|
|
public static String fixJsonStr(String str) { |
|
|
|
// 如果包含"...",那么就截取掉,在商品中不会出现,并且在json应该只会出现一次,如果会出现多次的话,那这里需要再次优化
|
|
|
|
if(str.contains("...")){ |
|
|
|
if (str.contains("...")) { |
|
|
|
final String[] newStr = COMPILED.split(str); |
|
|
|
final int newStrLength = newStr.length; |
|
|
|
if(newStrLength ==2){ |
|
|
|
if (newStrLength == 2) { |
|
|
|
// 第一个字符串从开头截取到第一个}
|
|
|
|
newStr[0] = newStr[0].substring(0, newStr[0].lastIndexOf('}')); |
|
|
|
// 第二个字符串从第一个{截取到最后
|
|
|
|
newStr[1] = newStr[1].substring(newStr[1].indexOf('{')); |
|
|
|
// 重新拼接,并且中间加上逗号
|
|
|
|
str = newStr[0]+ ',' +newStr[1]; |
|
|
|
str = newStr[0] + ',' + newStr[1]; |
|
|
|
} |
|
|
|
} |
|
|
|
str = str.replace("productCounts", "productCount"); |
|
|
|
@ -487,7 +488,7 @@ public class AliOcrUtil { |
|
|
|
* @author 王富康 |
|
|
|
* @date 2024/5/10 |
|
|
|
*/ |
|
|
|
public static JSONObject streamCall(PurchaseOcrPicture purchaseOcrPicture, PurchaseOcrExample purchaseOcrExample, ProductService productService, PurchaseDetailService purchaseDetailService) |
|
|
|
public static JSONObject streamCall(PurchaseOcrPicture purchaseOcrPicture, PurchaseOcrExample purchaseOcrExample, ProductService productService, PurchaseDetailService purchaseDetailService, ProductCategoryService productCategoryService) |
|
|
|
throws ApiException, NoApiKeyException, UploadFileException { |
|
|
|
final JSONObject jsonObject = new JSONObject(); |
|
|
|
final String picturePath = purchaseOcrPicture.getOcrPicture(); |
|
|
|
@ -574,7 +575,7 @@ public class AliOcrUtil { |
|
|
|
/*if (StringUtils.isNotEmpty(parentPicturePath)) { |
|
|
|
picturePath = parentPicturePath; |
|
|
|
}*/ |
|
|
|
getPurchaseDetailMap(purchaseDetailService, productService, orderId, shopId, picturePath, json); |
|
|
|
getPurchaseDetailMap(purchaseDetailService, productService, orderId, shopId, picturePath, json, productCategoryService); |
|
|
|
stopWatch.stop(); |
|
|
|
|
|
|
|
log.info(stopWatch.prettyPrint()); |
|
|
|
@ -597,7 +598,7 @@ public class AliOcrUtil { |
|
|
|
* @author 王富康 |
|
|
|
* @date 2024/3/31 |
|
|
|
*/ |
|
|
|
private static void getPurchaseDetailMap(PurchaseDetailService purchaseDetailService, ProductService productService, String orderId, String shopId, String ocrPicturePath, JSONArray json) { |
|
|
|
private static void getPurchaseDetailMap(PurchaseDetailService purchaseDetailService, ProductService productService, String orderId, String shopId, String ocrPicturePath, JSONArray json, ProductCategoryService productCategoryService) { |
|
|
|
// 开始解析图片识别的数据,进行入库操作。
|
|
|
|
// 解析未实体对象
|
|
|
|
final CopyOnWriteArrayList<PurchaseOcrVo> purchaseOcrVos = new CopyOnWriteArrayList<>(); |
|
|
|
@ -608,7 +609,10 @@ public class AliOcrUtil { |
|
|
|
for (int i = 0; i < json.size(); i++) { |
|
|
|
final JSONObject jsonObject = json.getJSONObject(i); |
|
|
|
final PurchaseOcrVo purchaseOcrVo = new PurchaseOcrVo(); |
|
|
|
purchaseOcrVo.setProductSn(jsonObject.getString("productSn")); |
|
|
|
String productSnOfJson = jsonObject.getString("productSn"); |
|
|
|
// 尝试从货号中提取正确的货号,因为货号可能包含颜色等信息
|
|
|
|
productSnOfJson = CommonUtil.getProductSn(productSnOfJson); |
|
|
|
purchaseOcrVo.setProductSn(productSnOfJson); |
|
|
|
purchaseOcrVo.setProductName(jsonObject.getString("productName")); |
|
|
|
purchaseOcrVo.setPrice(jsonObject.getBigDecimal("price")); |
|
|
|
final String productCount = jsonObject.getString("productCount"); |
|
|
|
@ -626,7 +630,7 @@ public class AliOcrUtil { |
|
|
|
|
|
|
|
final CopyOnWriteArrayList<PurchaseOcrDetailVo> attributeList = new CopyOnWriteArrayList<>(); |
|
|
|
final String size = attributeListJson.getString("size"); |
|
|
|
if(size.contains(",")){ |
|
|
|
if (size.contains(",")) { |
|
|
|
final String[] sizeArray = size.split(","); |
|
|
|
for (String s : sizeArray) { |
|
|
|
final PurchaseOcrDetailVo purchaseOcrDetailVo = new PurchaseOcrDetailVo(); |
|
|
|
@ -634,7 +638,7 @@ public class AliOcrUtil { |
|
|
|
purchaseOcrDetailVo.setSize(s); |
|
|
|
attributeList.add(purchaseOcrDetailVo); |
|
|
|
} |
|
|
|
}else if(size.contains("-")){ |
|
|
|
} else if (size.contains("-")) { |
|
|
|
final String[] sizeArray = size.split("-"); |
|
|
|
for (String s : sizeArray) { |
|
|
|
final PurchaseOcrDetailVo purchaseOcrDetailVo = new PurchaseOcrDetailVo(); |
|
|
|
@ -642,7 +646,7 @@ public class AliOcrUtil { |
|
|
|
purchaseOcrDetailVo.setSize(s); |
|
|
|
attributeList.add(purchaseOcrDetailVo); |
|
|
|
} |
|
|
|
}else{ |
|
|
|
} else { |
|
|
|
final PurchaseOcrDetailVo purchaseOcrDetailVo = new PurchaseOcrDetailVo(); |
|
|
|
purchaseOcrDetailVo.setColor(attributeListJson.getString("color")); |
|
|
|
purchaseOcrDetailVo.setSize(size); |
|
|
|
@ -794,6 +798,12 @@ public class AliOcrUtil { |
|
|
|
purchaseDetail.setWholesalePrice(product.getWholesalePrice()); |
|
|
|
purchaseDetail.setProductName(product.getProductName()); |
|
|
|
stockLog.setProductId(product.getId()); |
|
|
|
}else{ |
|
|
|
// 新商品,获取默认分类
|
|
|
|
final ProductCategoryVo defaultCategory = productCategoryService.getDefaultCategory(shopId); |
|
|
|
if (defaultCategory != null) { |
|
|
|
purchaseDetail.setCategoryId(defaultCategory.getCategoryId()); |
|
|
|
} |
|
|
|
} |
|
|
|
stockLogList.add(stockLog); |
|
|
|
purchaseDetail.setStockLogList1(stockLogList); |
|
|
|
@ -822,7 +832,11 @@ public class AliOcrUtil { |
|
|
|
final MessageManager msgManager = new MessageManager(10); |
|
|
|
final Message systemMsg = |
|
|
|
Message.builder().role(Role.SYSTEM.getValue()).content("You are a helpful assistant.").build(); |
|
|
|
questionMsg += "请帮我把所有内容封装为JSON,json格式为:[{ \"productSn\": \"货号\", \"attributeList\": [{\"color\":\"颜色\",\"size\":\"尺码\",\"productCount\": \"数量\"}] }],只输出JSON数据即可,不用返回字段描述"; |
|
|
|
//questionMsg += "请帮我把所有内容封装为JSON,json格式为:[{ \"productSn\": \"货号\", \"attributeList\": [{\"color\":\"颜色\",\"size\":\"尺码\",\"productCount\": \"数量\"}] }]。以下是几点要求: 1.“货号”两个字和颜色中间的内容代表productSn,productSn可能包含\"新\"、\"退\"、\"旧\"、\"换\"、\"补\"。 2.\"SYYS色\"代表“所有颜色”,\"color\"字段返回“SYYS色”。 3.\"SYCM码\"代表“所有尺码”,\"size\"字段返回“SYCM码”。 4.只输出JSON数据即可,不用返回字段描述和解析过程。";
|
|
|
|
questionMsg += "请帮我把所有内容封装为JSON,json格式为:[{ \"productSn\": \"货号\", \"attributeList\": [{\"color\":\"颜色\",\"size\":\"尺码\",\"productCount\": \"数量\"}] }]," + |
|
|
|
"productSn的返回值中去掉颜色,尺码等信息,\n" + |
|
|
|
"如果没有识别到\"color\"的内容,则\"color\"赋值“均色”。如果没有识别到\"size\"的内容,则\"size\"赋值“均码”,\n" + |
|
|
|
"只输出JSON数据即可,不用返回字段描述。"; |
|
|
|
final Message userMsg = Message.builder().role(Role.USER.getValue()).content(questionMsg).build(); |
|
|
|
msgManager.add(systemMsg); |
|
|
|
msgManager.add(userMsg); |
|
|
|
@ -830,10 +844,6 @@ public class AliOcrUtil { |
|
|
|
final QwenParam param = |
|
|
|
QwenParam.builder().model(Generation.Models.QWEN_PLUS).messages(msgManager.get()) |
|
|
|
.resultFormat(QwenParam.ResultFormat.MESSAGE) |
|
|
|
.temperature(1F) |
|
|
|
.topP(0.1) |
|
|
|
.topK(1) |
|
|
|
.seed(500) |
|
|
|
.build(); |
|
|
|
final GenerationResult result = gen.call(param); |
|
|
|
log.info(result.toString()); |
|
|
|
@ -850,6 +860,48 @@ public class AliOcrUtil { |
|
|
|
return jsonObject; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* ai语音入库 |
|
|
|
* |
|
|
|
* @param questionMsg |
|
|
|
* @return JSONObject |
|
|
|
* @author 王富康 |
|
|
|
* @date 2024/5/23 |
|
|
|
*/ |
|
|
|
public static JSONObject callWithMessageOfPurchase(String questionMsg) |
|
|
|
throws NoApiKeyException, ApiException, InputRequiredException { |
|
|
|
final JSONObject jsonObject = new JSONObject(); |
|
|
|
Constants.apiKey = "sk-bcfa4865b89548acb8225f910f13d682"; |
|
|
|
final Generation gen = new Generation(); |
|
|
|
final MessageManager msgManager = new MessageManager(10); |
|
|
|
final Message systemMsg = |
|
|
|
Message.builder().role(Role.SYSTEM.getValue()).content("You are a helpful assistant.").build(); |
|
|
|
// questionMsg += "请帮我把所有内容封装为JSON,json格式为:[{ \"productSn\": \"货号\", \"productName\": \"名称\" , \"price\":\"单价\",\"attributeList\": [{\"color\":\"颜色\",\"size\":\"尺码\",\"productCount\": \"数量\"}] }]。以下是几点要求: 1.“货号”两个字和\"名称\"两个字中间的内容代表productSn的值,如果没有名称则“货号”两个字和颜色中间的内容代表productSn的值,productSn可能包含\"新\"、\"退\"、\"旧\"、\"换\"、\"补\"。2.\"SYYS色\"代表“所有颜色”,\"color\"字段返回“SYYS色”。 3.\"SYCM码\"代表“所有尺码”,\"size\"字段返回“SYCM码”。4.如果没有名称,productName字段返回\"\"。5.只输出JSON数据即可,不用返回字段描述和解析过程。";
|
|
|
|
questionMsg += "请帮我把所有内容封装为JSON,json格式为:[{ \"productSn\": \"货号\", \"productName\": \"名称\" , \"attributeList\": [{\"color\":\"颜色\",\"size\":\"尺码\",\"productCount\": \"数量\"}], \"price\":\"单价\" }]," + |
|
|
|
"如果没有识别到\"price\"的内容,则\"price\"赋值\"0\"," + |
|
|
|
"如果没有识别到\"color\"的内容,则\"color\"赋值“均色”," + |
|
|
|
"如果没有识别到\"size\"的内容,则\"size\"赋值“均码”,\n" + |
|
|
|
"如果没有识别到\"productName\"的内容,则\"productName\"使用\"productSn\"的值填充。只输出JSON数据即可,不用返回字段描述。"; |
|
|
|
final Message userMsg = Message.builder().role(Role.USER.getValue()).content(questionMsg).build(); |
|
|
|
msgManager.add(systemMsg); |
|
|
|
msgManager.add(userMsg); |
|
|
|
final QwenParam param = |
|
|
|
QwenParam.builder().model(Generation.Models.QWEN_PLUS).messages(msgManager.get()) |
|
|
|
.resultFormat(QwenParam.ResultFormat.MESSAGE) |
|
|
|
.build(); |
|
|
|
final GenerationResult result = gen.call(param); |
|
|
|
log.info(result.toString()); |
|
|
|
// 解析结果
|
|
|
|
final String text = result.getOutput().getChoices().get(0).getMessage().getContent(); |
|
|
|
// 根据{}截取数据
|
|
|
|
final int startIndex = text.indexOf('{'); |
|
|
|
final int endIndex = text.lastIndexOf('}'); |
|
|
|
final String jsonStr = '[' + text.substring(startIndex, endIndex + 1) + ']'; |
|
|
|
jsonObject.put("resultContent", jsonStr); |
|
|
|
jsonObject.put("msg", result.getOutput().getChoices().get(0).getMessage().getContent()); |
|
|
|
return jsonObject; |
|
|
|
} |
|
|
|
|
|
|
|
public static JSONObject callWithMessageSync(String questionMsg, String saleId, String shopId, String createBy, ProductService productService, ProductCategoryService productCategoryService, SaleService saleService, SaleDetailService saleDetailService) |
|
|
|
throws NoApiKeyException, ApiException, InputRequiredException { |
|
|
|
final JSONObject jsonObject = new JSONObject(); |
|
|
|
@ -859,7 +911,11 @@ public class AliOcrUtil { |
|
|
|
final MessageManager msgManager = new MessageManager(10); |
|
|
|
final Message systemMsg = |
|
|
|
Message.builder().role(Role.SYSTEM.getValue()).content("You are a helpful assistant.").build(); |
|
|
|
questionMsg += "请帮我把所有内容封装为JSON,json格式为:[{ \"productSn\": \"货号\", \"attributeList\": [{\"color\":\"颜色\",\"size\":\"尺码\",\"productCount\": \"数量\"}] }],只输出JSON数据即可,不用返回字段描述"; |
|
|
|
// questionMsg += "请帮我把所有内容封装为JSON,json格式为:[{ \"productSn\": \"货号\", \"attributeList\": [{\"color\":\"颜色\",\"size\":\"尺码\",\"productCount\": \"数量\"}] }],只输出JSON数据即可,不用返回字段描述";
|
|
|
|
questionMsg += "请帮我把所有内容封装为JSON,json格式为:[{ \"productSn\": \"货号\", \"attributeList\": [{\"color\":\"颜色\",\"size\":\"尺码\",\"productCount\": \"数量\"}] }]," + |
|
|
|
"productSn的返回值中去掉颜色,尺码等信息,\n" + |
|
|
|
"如果没有识别到\"color\"的内容,则\"color\"赋值“均色”。如果没有识别到\"size\"的内容,则\"size\"赋值“均码”,\n" + |
|
|
|
"只输出JSON数据即可,不用返回字段描述。"; |
|
|
|
final Message userMsg = Message.builder().role(Role.USER.getValue()).content(questionMsg).build(); |
|
|
|
msgManager.add(systemMsg); |
|
|
|
msgManager.add(userMsg); |
|
|
|
@ -867,10 +923,6 @@ public class AliOcrUtil { |
|
|
|
final QwenParam param = |
|
|
|
QwenParam.builder().model(Generation.Models.QWEN_PLUS).messages(msgManager.get()) |
|
|
|
.resultFormat(QwenParam.ResultFormat.MESSAGE) |
|
|
|
.temperature(1F) |
|
|
|
.topP(0.1) |
|
|
|
.topK(1) |
|
|
|
.seed(500) |
|
|
|
.build(); |
|
|
|
final GenerationResult result = gen.call(param); |
|
|
|
log.info(result.toString()); |
|
|
|
@ -911,8 +963,10 @@ public class AliOcrUtil { |
|
|
|
final CopyOnWriteArrayList<SaleDetail> saleDetailList = new CopyOnWriteArrayList<>(); |
|
|
|
for (int i = 0; i < json.size(); i++) { |
|
|
|
final JSONObject object = json.getJSONObject(i); |
|
|
|
final String productSn = object.getString("productSn"); |
|
|
|
// 根据货号去查询商品,如果
|
|
|
|
String productSn = object.getString("productSn"); |
|
|
|
// 尝试从货号中提取正确的货号,因为货号可能包含颜色等信息
|
|
|
|
productSn = CommonUtil.getProductSn(productSn); |
|
|
|
// 根据货号去查询商品
|
|
|
|
final CopyOnWriteArrayList<Product> byProductSn = productService.getByProductSn(productSn, shopId); |
|
|
|
if (byProductSn != null && !byProductSn.isEmpty()) { |
|
|
|
// 原则上一个店铺一个货号对应一个商品,这里如果查到了,直接拿第一个。
|
|
|
|
|