@ -28,7 +28,12 @@ import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired ;
import org.springframework.stereotype.Component ;
import java.util.* ;
import java.util.Arrays ;
import java.util.Collections ;
import java.util.Date ;
import java.util.Map ;
import java.util.concurrent.ConcurrentHashMap ;
import java.util.concurrent.CopyOnWriteArrayList ;
import java.util.regex.Pattern ;
@Slf4j
@ -62,7 +67,7 @@ public class AliOcrUtil {
final StopWatch stopWatch = new StopWatch ( "Ai回答计时" ) ;
Constants . apiKey = "sk-bcfa4865b89548acb8225f910f13d682" ;
final List < MultiModalConversationResult > multiModalConversationResults = new ArrayList < > ( ) ;
final CopyOnWriteArray List< MultiModalConversationResult > multiModalConversationResults = new CopyOnWrite ArrayList< > ( ) ;
final MultiModalConversation conv = new MultiModalConversation ( ) ;
final MultiModalMessageItemText systemText = new MultiModalMessageItemText ( "You are a helpful assistant." ) ;
final MultiModalConversationMessage systemMessage = MultiModalConversationMessage . builder ( )
@ -74,7 +79,7 @@ public class AliOcrUtil {
final MultiModalConversationMessage userMessage =
MultiModalConversationMessage . builder ( ) . role ( Role . USER . getValue ( ) )
. content ( Arrays . asList ( userImage , userText ) ) . build ( ) ;
final List < MultiModalConversationMessage > messages = new ArrayList < > ( ) ;
final CopyOnWriteArray List< MultiModalConversationMessage > messages = new CopyOnWrite ArrayList< > ( ) ;
messages . add ( systemMessage ) ;
messages . add ( userMessage ) ;
final MultiModalConversationParam param = MultiModalConversationParam . builder ( )
@ -94,9 +99,9 @@ public class AliOcrUtil {
// 根据{}截取数据
final int startIndex = text . indexOf ( '{' ) ;
final int endIndex = text . lastIndexOf ( '}' ) ;
if ( startIndex = = - 1 | | endIndex = = - 1 ) {
if ( startIndex = = - 1 | | endIndex = = - 1 ) {
// 没有查询到想要的数据,那么就报错返回
throw new RuntimeException ( "识别数据失败,未找到指定标识符:识别结果为:" + text ) ;
throw new RuntimeException ( "识别数据失败,未找到指定标识符:识别结果为:" + text ) ;
}
final String jsonStr = '[' + text . substring ( startIndex , endIndex + 1 ) + ']' ;
JSONArray json = JSON . parseArray ( jsonStr ) ;
@ -113,7 +118,7 @@ public class AliOcrUtil {
userText = new MultiModalMessageItemText ( secondQuestionMsg ) ;
messages . add ( MultiModalConversationMessage . builder ( ) . role ( Role . USER . getValue ( ) )
. content ( Collections . singletonList ( userText ) ) . build ( ) ) ;
param . setMessages ( new ArrayList < Object > ( messages ) ) ;
param . setMessages ( new CopyOnWrite ArrayList< Object > ( messages ) ) ;
stopWatch . start ( "二轮会话" ) ;
result = conv . call ( param ) ;
multiModalConversationResults . add ( result ) ;
@ -129,13 +134,13 @@ public class AliOcrUtil {
log . info ( JSON . toJSONString ( json ) ) ;
stopWatch . start ( "解析结果==" ) ;
// 解析结果
final Map < String , PurchaseDetail > purchaseDetailMap = getPurchaseDetailMap ( productService , orderId , shopId , picturePath , json ) ;
getPurchaseDetailMap ( purchaseDetailService , productService , orderId , shopId , picturePath , json ) ;
stopWatch . stop ( ) ;
// 将map 转为list 进行落库操作
stopWatch . start ( "批量插入==" ) ;
final List < PurchaseDetail > purchaseDetails = new ArrayList < > ( purchaseDetailMap . values ( ) ) ;
/ * stopWatch . start ( "批量插入==" ) ;
final CopyOnWriteArray List< PurchaseDetail > purchaseDetails = new CopyOnWrite ArrayList< > ( purchaseDetailMap . values ( ) ) ;
purchaseDetailService . batchSavePurchaseList ( purchaseDetails ) ;
stopWatch . stop ( ) ;
stopWatch . stop ( ) ; * /
log . info ( stopWatch . prettyPrint ( ) ) ;
jsonObject . put ( "resultContent" , json ) ;
@ -157,15 +162,14 @@ public class AliOcrUtil {
* @author 王富康
* @date 2024 / 3 / 31
* /
@NotNull
private static Map < String , PurchaseDetail > getPurchaseDetailMap ( 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 ) {
// 开始解析图片识别的数据,进行入库操作。
// 解析未实体对象
final List < PurchaseOcrVo > purchaseOcrVos = new ArrayList < > ( ) ;
final CopyOnWriteArray List< PurchaseOcrVo > purchaseOcrVos = new CopyOnWrite ArrayList< > ( ) ;
// 货号集合
final List < String > productSnList = new ArrayList < > ( ) ;
final CopyOnWriteArray List< String > productSnList = new CopyOnWrite ArrayList< > ( ) ;
// 商品名称集合
final List < String > productNameList = new ArrayList < > ( ) ;
final CopyOnWriteArray List< String > productNameList = new CopyOnWrite ArrayList< > ( ) ;
for ( int i = 0 ; i < json . size ( ) ; i + + ) {
final JSONObject jsonObject = json . getJSONObject ( i ) ;
final PurchaseOcrVo purchaseOcrVo = new PurchaseOcrVo ( ) ;
@ -178,7 +182,9 @@ public class AliOcrUtil {
final PurchaseOcrDetailVo purchaseOcrDetailVo = new PurchaseOcrDetailVo ( ) ;
purchaseOcrDetailVo . setColor ( attributeListJson . getString ( "color" ) ) ;
purchaseOcrDetailVo . setSize ( attributeListJson . getString ( "size" ) ) ;
purchaseOcrVo . setAttributeList ( Collections . singletonList ( purchaseOcrDetailVo ) ) ;
final CopyOnWriteArrayList < PurchaseOcrDetailVo > attributeList = new CopyOnWriteArrayList < > ( ) ;
attributeList . add ( purchaseOcrDetailVo ) ;
purchaseOcrVo . setAttributeList ( attributeList ) ;
purchaseOcrVos . add ( purchaseOcrVo ) ;
// 处理当前识别的货号及名称,现在需要特殊处理的 是货号:去掉“/”,或者是“/"在货号或者名称中间的,需要分隔为货号及名称
@ -223,22 +229,22 @@ public class AliOcrUtil {
purchaseOcrVo . setProductName ( productName ) ;
}
// 根据货号集合获取商品信息
final List < Product > productByProductSnList = productService . getProductByProductSnList ( productSnList , shopId ) ;
final Map < String , Product > productSnMap = new HashMap < > ( ) ;
final CopyOnWriteArray List< Product > productByProductSnList = productService . getProductByProductSnList ( productSnList , shopId ) ;
final Map < String , Product > productSnMap = new Concurrent HashMap< > ( ) ;
// 将商品信息封装到Map 中,货号作为key,商品作为value
productByProductSnList . forEach ( product - > {
productSnMap . put ( product . getProductSn ( ) , product ) ;
} ) ;
// 根据商品名称获取商品信息
final List < Product > productByProductNameList = productService . getProductByProductNameList ( productNameList , shopId ) ;
final Map < String , Product > productNameMap = new HashMap < > ( ) ;
final CopyOnWriteArray List< Product > productByProductNameList = productService . getProductByProductNameList ( productNameList , shopId ) ;
final Map < String , Product > productNameMap = new Concurrent HashMap< > ( ) ;
// 将商品信息封装到Map 中,商品名称作为key,商品作为value
productByProductNameList . forEach ( product - > {
productNameMap . put ( product . getProductName ( ) , product ) ;
} ) ;
// 得到数据之后,开始跟该店铺的商品进行对比。
// orderId
final Map < String , PurchaseDetail > purchaseDetailMap = new HashMap < > ( ) ;
final Map < String , PurchaseDetail > purchaseDetailMap = new Concurrent HashMap< > ( ) ;
for ( PurchaseOcrVo purchaseOcrVo : purchaseOcrVos ) {
String productSn = purchaseOcrVo . getProductSn ( ) ;
final String productName = purchaseOcrVo . getProductName ( ) ;
@ -254,7 +260,7 @@ public class AliOcrUtil {
}
}
// 先将规格信息拼接好,后边肯定会插入这个值
final List < PurchaseOcrDetailVo > attributeList = purchaseOcrVo . getAttributeList ( ) ;
final CopyOnWriteArray List< PurchaseOcrDetailVo > attributeList = purchaseOcrVo . getAttributeList ( ) ;
final StringBuilder attributeStr = new StringBuilder ( ) ;
// 现在的读取方式是一个商品一个规格,attributeList 的长度目前只是1。
for ( PurchaseOcrDetailVo purchaseOcrDetailVo : attributeList ) {
@ -292,7 +298,7 @@ public class AliOcrUtil {
} else {
final PurchaseDetail purchaseDetail = new PurchaseDetail ( ) ;
final StockLog stockLog = new StockLog ( ) ;
final List < StockLog > stockLogList = new ArrayList < > ( ) ;
final CopyOnWriteArray List< StockLog > stockLogList = new CopyOnWrite ArrayList< > ( ) ;
purchaseDetail . setPurchaseId ( orderId ) ;
purchaseDetail . setCreateTime ( new Date ( ) ) ;
purchaseDetail . setShopId ( shopId ) ;
@ -328,7 +334,8 @@ public class AliOcrUtil {
purchaseDetailMap . put ( StringUtils . isEmpty ( productSn ) ? productName : productSn , purchaseDetail ) ;
}
}
return purchaseDetailMap ;
final CopyOnWriteArrayList < PurchaseDetail > purchaseDetails = new CopyOnWriteArrayList < > ( purchaseDetailMap . values ( ) ) ;
purchaseDetailService . batchSavePurchaseList ( purchaseDetails ) ;
}
/ * *
@ -431,15 +438,15 @@ public class AliOcrUtil {
@NotNull
private static void getSaleList ( String saleId , String jsonStr , String shopId , String createBy , ProductService productService , ProductCategoryService productCategoryService , SaleService saleService , SaleDetailService saleDetailService ) {
final List < String > aiNotRecognitionList = new ArrayList < > ( ) ;
final CopyOnWriteArray List< String > aiNotRecognitionList = new CopyOnWrite ArrayList< > ( ) ;
// 异步处理的直接入库
final JSONArray json = JSON . parseArray ( jsonStr ) ;
final List < SaleDetail > saleDetailList = new ArrayList < > ( ) ;
final CopyOnWriteArray List< SaleDetail > saleDetailList = new CopyOnWrite ArrayList< > ( ) ;
for ( int i = 0 ; i < json . size ( ) ; i + + ) {
final JSONObject object = json . getJSONObject ( i ) ;
final String productSn = object . getString ( "productSn" ) ;
// 根据货号去查询商品,如果
final List < Product > byProductSn = productService . getByProductSn ( productSn , shopId ) ;
final CopyOnWriteArray List< Product > byProductSn = productService . getByProductSn ( productSn , shopId ) ;
if ( byProductSn ! = null & & ! byProductSn . isEmpty ( ) ) {
// 原则上一个店铺一个货号对应一个商品,这里如果查到了,直接拿第一个。
final Product product = byProductSn . get ( 0 ) ;
@ -462,24 +469,24 @@ public class AliOcrUtil {
}
size = size . toUpperCase ( ) ;
final List < String > categoryIdList = new ArrayList < > ( ) ;
final CopyOnWriteArray List< String > categoryIdList = new CopyOnWrite ArrayList< > ( ) ;
categoryIdList . add ( categoryId ) ;
// 查询该店铺该分类下所有的颜色和尺码,进行对比,有则新增,无,则提醒用户无该规格
final List < ProductCategoryVo > shopCategory = productCategoryService . getShopCategory ( categoryIdList ) ;
final CopyOnWriteArray List< ProductCategoryVo > shopCategory = productCategoryService . getShopCategory ( categoryIdList ) ;
final ProductCategoryVo productCategoryVo = shopCategory . get ( 0 ) ;
final List < ProductAttributeOfAddVo > productAttributeOfAddVos = productCategoryVo . getProductAttributeOfAddVos ( ) ;
final Map < String , ProductAttributeOfAddVo > productAttributeOfAddVoMap = new HashMap < > ( ) ;
final CopyOnWriteArray List< ProductAttributeOfAddVo > productAttributeOfAddVos = productCategoryVo . getProductAttributeOfAddVos ( ) ;
final Map < String , ProductAttributeOfAddVo > productAttributeOfAddVoMap = new Concurrent HashMap< > ( ) ;
for ( ProductAttributeOfAddVo productAttributeOfAddVo : productAttributeOfAddVos ) {
productAttributeOfAddVoMap . put ( productAttributeOfAddVo . getAttributeName ( ) , productAttributeOfAddVo ) ;
}
//获取颜色及规格进行拼接
List < ProductAttributeValueVo > colorProductAttributeValueVoList = new ArrayList < > ( ) ;
List < ProductAttributeValueVo > sizeProductAttributeValueVoList = new ArrayList < > ( ) ;
CopyOnWriteArray List< ProductAttributeValueVo > colorProductAttributeValueVoList = new CopyOnWrite ArrayList< > ( ) ;
CopyOnWriteArray List< ProductAttributeValueVo > sizeProductAttributeValueVoList = new CopyOnWrite ArrayList< > ( ) ;
if ( productAttributeOfAddVoMap . containsKey ( "颜色" ) ) {
colorProductAttributeValueVoList = productAttributeOfAddVoMap . get ( "颜色" ) . getProductAttributeValueVoList ( ) ;
}
// 将所有颜色放到一个集合中
final List < String > colorList = new ArrayList < > ( ) ;
final CopyOnWriteArray List< String > colorList = new CopyOnWrite ArrayList< > ( ) ;
for ( ProductAttributeValueVo productAttributeValueVo : colorProductAttributeValueVoList ) {
colorList . add ( productAttributeValueVo . getValue ( ) ) ;
}
@ -487,7 +494,7 @@ public class AliOcrUtil {
sizeProductAttributeValueVoList = productAttributeOfAddVoMap . get ( "尺码" ) . getProductAttributeValueVoList ( ) ;
}
// 将所有尺码放到一个集合中
final List < String > sizeList = new ArrayList < > ( ) ;
final CopyOnWriteArray List< String > sizeList = new CopyOnWrite ArrayList< > ( ) ;
for ( ProductAttributeValueVo productAttributeValueVo : sizeProductAttributeValueVoList ) {
sizeList . add ( productAttributeValueVo . getValue ( ) ) ;
}
@ -619,6 +626,8 @@ public class AliOcrUtil {
}
} else {
// 没查到去找下一个
final String msg = "货号为:" + productSn + "的商品,不存在" ;
aiNotRecognitionList . add ( msg ) ;
continue ;
}