From e51984e13a7188be703ca6dc9fdb893944a9a570 Mon Sep 17 00:00:00 2001 From: wangfukang <15630117759@163.com> Date: Thu, 18 Jul 2024 09:18:44 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8B=BF=E8=B4=A7=E6=80=BB=E9=87=91=E9=A2=9D?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hiver-admin/test-output/test-report.html | 16 ++-- .../mall/pojo/vo/CustomerSaleDetailVo.java | 2 +- .../PurchaseOcrPictureController.java | 18 +++++ .../service/PurchaseOcrPictureService.java | 2 + .../impl/PurchaseOcrPictureServiceImpl.java | 73 +++++++++++++++++++ .../mall/purchaseocr/vo/CustomInfoOfAiVo.java | 37 ++++++++++ .../java/cc/hiver/mall/utils/AliOcrUtil.java | 62 +++++++++++----- .../src/main/resources/mapper/SaleMapper.xml | 4 +- 8 files changed, 184 insertions(+), 30 deletions(-) create mode 100644 hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/purchaseocr/vo/CustomInfoOfAiVo.java diff --git a/hiver-admin/test-output/test-report.html b/hiver-admin/test-output/test-report.html index 7721184e..e8dcce60 100644 --- a/hiver-admin/test-output/test-report.html +++ b/hiver-admin/test-output/test-report.html @@ -35,7 +35,7 @@ Hiver
  • - 12, 2024 11:22:46 + 17, 2024 16:39:09
  • @@ -84,7 +84,7 @@

    passTest

    -

    11:22:47 / 0.045 secs

    +

    16:39:10 / 0.017 secs

    @@ -92,9 +92,9 @@
    #test-id=1
    passTest
    -07.12.2024 11:22:47 -07.12.2024 11:22:47 -0.045 secs +07.17.2024 16:39:10 +07.17.2024 16:39:10 +0.017 secs
    @@ -104,7 +104,7 @@ Pass - 11:22:47 + 16:39:10 Test passed @@ -128,13 +128,13 @@

    Started

    -

    12, 2024 11:22:46

    +

    17, 2024 16:39:09

    Ended

    -

    12, 2024 11:22:47

    +

    17, 2024 16:39:10

    diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/pojo/vo/CustomerSaleDetailVo.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/pojo/vo/CustomerSaleDetailVo.java index 4ce4c75f..4352f850 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/pojo/vo/CustomerSaleDetailVo.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/pojo/vo/CustomerSaleDetailVo.java @@ -18,7 +18,7 @@ public class CustomerSaleDetailVo { private String productCount; @ApiModelProperty(value = " 拿货总金额") - private String totalAmount; + private String realAmount; @ApiModelProperty(value = " 成本") private String totalCost; diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/purchaseocr/controller/PurchaseOcrPictureController.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/purchaseocr/controller/PurchaseOcrPictureController.java index 5fafb518..ee88b2d7 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/purchaseocr/controller/PurchaseOcrPictureController.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/purchaseocr/controller/PurchaseOcrPictureController.java @@ -1,6 +1,7 @@ package cc.hiver.mall.purchaseocr.controller; import cc.hiver.core.common.utils.ResultUtil; +import cc.hiver.core.common.utils.StringUtils; import cc.hiver.core.common.vo.Result; import cc.hiver.mall.purchaseocr.service.PurchaseOcrPictureService; import cc.hiver.mall.purchaseocr.vo.PurchaseOciPictureAddVo; @@ -66,4 +67,21 @@ public class PurchaseOcrPictureController { final List multiModalConversationResults = purchaseOcrPictureService.multiRoundConversationCall(picturePath, count); return multiModalConversationResults; } + + /** + * 物流公司AI解析用户信息 + * @author 王富康 + * @date 2024/7/17 + * @param questionMsg + * @return Result + */ + @RequestMapping(value = "/getCustomInfoOfAi", method = RequestMethod.POST) + @ApiOperation("物流公司AI解析用户信息") + public Result getCustomInfoOfAi(String questionMsg) { + if(StringUtils.isEmpty(questionMsg)){ + return ResultUtil.error("信息不能为空!"); + } + JSONObject jsonObject = purchaseOcrPictureService.getCustomInfoOfAi(questionMsg); + return ResultUtil.data(jsonObject); + } } diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/purchaseocr/service/PurchaseOcrPictureService.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/purchaseocr/service/PurchaseOcrPictureService.java index 98d8cf3d..333deb80 100644 --- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/purchaseocr/service/PurchaseOcrPictureService.java +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/purchaseocr/service/PurchaseOcrPictureService.java @@ -25,4 +25,6 @@ public interface PurchaseOcrPictureService { List getOcrCount(); JSONObject callWithMessageOfPurchase(String questionMsg) throws NoApiKeyException, InputRequiredException; + + JSONObject getCustomInfoOfAi(String questionMsg); } 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 af1ad347..2ba08616 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 @@ -14,6 +14,7 @@ import cc.hiver.mall.pojo.vo.PurchaseVo; import cc.hiver.mall.purchaseocr.entity.PurchaseOcrPicture; import cc.hiver.mall.purchaseocr.mapper.PurchaseOcrPictureMapper; import cc.hiver.mall.purchaseocr.service.PurchaseOcrPictureService; +import cc.hiver.mall.purchaseocr.vo.CustomInfoOfAiVo; import cc.hiver.mall.purchaseocr.vo.PurchaseOciPictureAddVo; import cc.hiver.mall.purchaseocr.vo.PurchaseOcrCountVo; import cc.hiver.mall.purchaseocr.vo.PurchaseOcrExample; @@ -445,6 +446,78 @@ public class PurchaseOcrPictureServiceImpl implements PurchaseOcrPictureService return returnJsonObject; } + @Override + public JSONObject getCustomInfoOfAi(String questionMsg) { + final JSONObject returnJsonObject = new JSONObject(); + final List customInfoOfAiVos = new ArrayList<>(); + try { + final JSONObject jsonObject = AliOcrUtil.callWithMessageOfLogistics(questionMsg); + final String resultContent = jsonObject.get("resultContent").toString(); + final JSONArray json = JSON.parseArray(resultContent); + for (int i = 0; i < json.size(); i++) { + final CustomInfoOfAiVo customInfoOfAiVo = new CustomInfoOfAiVo(); + final JSONObject object = json.getJSONObject(i); + final String senderName = object.getString("senderName"); + customInfoOfAiVo.setSenderName(senderName); + final String senderPhone = object.getString("senderPhone"); + customInfoOfAiVo.setSenderPhone(senderPhone); + final String receiverName = object.getString("receiverName"); + customInfoOfAiVo.setReceiverName(receiverName); + final String receiverPhone = object.getString("receiverPhone"); + customInfoOfAiVo.setReceiverPhone(receiverPhone); + final String arrivalStation = object.getString("arrivalStation"); + customInfoOfAiVo.setArrivalStation(arrivalStation); + final String weightStr = object.getString("weight"); + BigDecimal weight = BigDecimal.ZERO; + // 使用正则表达式提取数字部分 + final Pattern pattern = Pattern.compile("-?\\d+(\\.\\d+)?"); + if(StringUtils.isNotEmpty(weightStr)){ + final Matcher matcher = pattern.matcher(weightStr); + if (matcher.find()) { + // 获取匹配到的数字字符串并转换为BigDecimal + final String numericPart = matcher.group(); + weight = new BigDecimal(numericPart); + + } + } + customInfoOfAiVo.setWeight(weight); + final String countStr = object.getString("count"); + int count = 0; + if(StringUtils.isNotEmpty(countStr)){ + final Matcher countMatchered = COMPILE.matcher(countStr); + String replaced = ""; + if (countMatchered.find()) { + replaced = countMatchered.group(); + } + count = Integer.parseInt(StringUtils.isEmpty(replaced) ? "0" : replaced); + } + + customInfoOfAiVo.setCount(count); + final String methodOfSettlement = object.getString("methodOfSettlement"); + customInfoOfAiVo.setMethodOfSettlement(methodOfSettlement); + final String tipsStr = object.getString("tips"); + BigDecimal tips = BigDecimal.ZERO; + if(StringUtils.isNotEmpty(tipsStr)){ + // 使用正则表达式提取数字部分 + final Matcher matcherOfTips = pattern.matcher(tipsStr); + if (matcherOfTips.find()) { + // 获取匹配到的数字字符串并转换为BigDecimal + final String numericPart = matcherOfTips.group(); + tips = new BigDecimal(numericPart); + + } + } + customInfoOfAiVo.setTips(tips); + customInfoOfAiVos.add(customInfoOfAiVo); + } + } catch (Exception e) { + log.error(e.getMessage(),e); + returnJsonObject.put("code", 500); + } + returnJsonObject.put("data", customInfoOfAiVos); + return returnJsonObject; + } + /** * 使用正则表达式替换输入字符串中连续的“叉”字符为相应数量的“X”字符。 * diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/purchaseocr/vo/CustomInfoOfAiVo.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/purchaseocr/vo/CustomInfoOfAiVo.java new file mode 100644 index 00000000..d916e6dd --- /dev/null +++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/purchaseocr/vo/CustomInfoOfAiVo.java @@ -0,0 +1,37 @@ +package cc.hiver.mall.purchaseocr.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; + +@Data +public class CustomInfoOfAiVo { + + @ApiModelProperty(value = "发货人") + private String senderName; + + @ApiModelProperty(value = "发货人电话") + private String senderPhone; + + @ApiModelProperty(value = "收货人") + private String receiverName; + + @ApiModelProperty(value = "收货人电话") + private String receiverPhone; + + @ApiModelProperty(value = "到达站") + private String arrivalStation; + + @ApiModelProperty(value = "重量") + private BigDecimal weight; + + @ApiModelProperty(value = "件数") + private Integer count; + + @ApiModelProperty(value = "结算方式") + private String methodOfSettlement; + + @ApiModelProperty(value = "小费") + private BigDecimal tips; +} 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 93238689..68cf0efd 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 @@ -588,7 +588,7 @@ public class AliOcrUtil { } /** - * 处理数据 + * 图像识别处理数据 * * @param productService * @param orderId @@ -818,7 +818,7 @@ public class AliOcrUtil { } /** - * AI开单 + * 语音-AI开单 * * @param questionMsg * @return JSONObject @@ -918,23 +918,6 @@ public class AliOcrUtil { return jsonObject; } - public static void main(String[] args) { - String aa = "请帮我把所有内容封装为JSON,json格式为:[{ \"productSn\": \"货号\", \"productName\": \"名称\" , \"attributeList\": [{\"color\":\"颜色\",\"size\":\"尺码\",\"productCount\": \"数量\"}], \"price\":\"单价\" }],\n" + - "1.如果没有识别到\"price\"的内容,则\"price\"赋值\"0\",\n" + - "2.如果没有识别到\"color\"的内容,则\"color\"赋值“均色”,\n" + - "3.如果没有识别到\"size\"的内容,则\"size\"赋值“均码”,\n" + - "4.如果没有识别到\"productName\"的内容,则\"productName\"使用\"productSn\"的值填充。\n" + - "5.如果没有识别到\"productSn\"的内容,则\"productSn\"赋值\"\",\n" + - "6.只输出JSON数据即可,不用返回字段描述。"; - String bb = "请帮我把所有内容封装为JSON,json格式为:[{ \"productSn\": \"货号\", \"attributeList\": [{\"color\":\"颜色\",\"size\":\"尺码\",\"productCount\": \"数量\"}] }],\n" + - "1.productSn的返回值中去掉颜色,尺码等信息,\n" + - "2.如果指令内容中有\"SYYS色\"则\"color\"字段返回“SYYS色”,\n" + - "3.如果指令内容中有\"SYCM码\"则\"size\"字段返回“SYCM码”,\n" + - "4.如果没有识别到\"color\"的内容,则\"color\"赋值“均色”。如果没有识别到\"size\"的内容,则\"size\"赋值“均码”,\n" + - "5.只输出JSON数据即可,不用返回字段描述。"; - - System.out.println(aa+"\n"+bb); - } 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(); @@ -1212,4 +1195,45 @@ public class AliOcrUtil { sale.setAiNotRecognition(newAiNotRecognition); saleService.saveOrUpdate(sale); } + + /** + * 语音-物流开单 + * + * @param questionMsg + * @return JSONObject + * @author 王富康 + * @date 2024/3/31 + */ + public static JSONObject callWithMessageOfLogistics (String questionMsg) + throws NoApiKeyException, ApiException, InputRequiredException { + final JSONObject jsonObject = new JSONObject(); + Constants.apiKey = "sk-bcfa4865b89548acb8225f910f13d682"; + final StopWatch stopWatch = new StopWatch("Ai回答计时"); + 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格式为:[{ \"senderName\": \"发货人\", \"senderPhone\": \"发货人电话\" , \"receiverName\": \"收货人\", \"receiverPhone\": \"收货人电话\" , \"arrivalStation\":\"\"到达站,\"weight\":\"重量\",\"count\":\"件数\",\"methodOfSettlement\":\"结算方式\",\"tips\":\"小费\" }]。没有识别到的信息JSON字段返回\"\"。"; + final Message userMsg = Message.builder().role(Role.USER.getValue()).content(questionMsg).build(); + msgManager.add(systemMsg); + msgManager.add(userMsg); + stopWatch.start("开始回答"); + final QwenParam param = + QwenParam.builder().model("qwen2-72b-instruct").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) + ']'; + stopWatch.stop(); + log.info(stopWatch.prettyPrint()); + jsonObject.put("resultContent", jsonStr); + jsonObject.put("msg", result.getOutput().getChoices().get(0).getMessage().getContent()); + return jsonObject; + } } \ No newline at end of file diff --git a/hiver-modules/hiver-mall/src/main/resources/mapper/SaleMapper.xml b/hiver-modules/hiver-mall/src/main/resources/mapper/SaleMapper.xml index 6e1e8400..5b7d2beb 100644 --- a/hiver-modules/hiver-mall/src/main/resources/mapper/SaleMapper.xml +++ b/hiver-modules/hiver-mall/src/main/resources/mapper/SaleMapper.xml @@ -1177,9 +1177,9 @@ trans_company, company_name, product_count, remark, sale_name, company_phone, cr ts.user_id, ts.user_name, sum(ts.product_count) as product_count, - sum(ts.total_amount) as total_amount, + sum(ts.total_amount) as real_amount, sum(cb.total_cost) as total_cost, - sum(ts.real_amount - cb.total_cost) as profit + sum(ts.total_amount - cb.total_cost) as profit FROM t_sale ts left join