diff --git a/hiver-core/src/main/java/cc/hiver/core/common/utils/CommonUtil.java b/hiver-core/src/main/java/cc/hiver/core/common/utils/CommonUtil.java
index a93ddbd7..78a0f9fe 100644
--- a/hiver-core/src/main/java/cc/hiver/core/common/utils/CommonUtil.java
+++ b/hiver-core/src/main/java/cc/hiver/core/common/utils/CommonUtil.java
@@ -1,20 +1,24 @@
package cc.hiver.core.common.utils;
import cn.hutool.core.util.IdUtil;
+import lombok.extern.slf4j.Slf4j;
import java.security.SecureRandom;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
/**
* 常用工具
*
* @author Yazhi Li
*/
+@Slf4j
public class CommonUtil {
private CommonUtil() {
throw new IllegalStateException("Utility class");
}
- private static SecureRandom random = new SecureRandom();
+ private static final SecureRandom random = new SecureRandom();
/**
* 以UUID重命名
@@ -25,7 +29,7 @@ public class CommonUtil {
public static String renamePic(String fileName) {
String extName = "";
if (fileName.contains(".")) {
- extName = fileName.substring(fileName.lastIndexOf("."));
+ extName = fileName.substring(fileName.lastIndexOf('.'));
}
return IdUtil.simpleUUID() + extName;
}
@@ -34,9 +38,9 @@ public class CommonUtil {
* 随机6位数生成
*/
public static String getRandomNum() {
- int num = random.nextInt(999999);
+ final int num = random.nextInt(999999);
// 不足六位前面补0
- String str = String.format("%06d", num);
+ final String str = String.format("%06d", num);
return str;
}
@@ -57,4 +61,18 @@ public class CommonUtil {
}
return flag;
}
+
+ public static String getProductSn(String productSn) {
+ log.info("需要提取的货号为:" + productSn);
+ // 更精确地假设货号在"商品名称:"之后,且紧跟着的是货号,直到遇到逗号
+ final Pattern pattern = Pattern.compile("([\\w.-]+)");
+ final Matcher matcher = pattern.matcher(productSn);
+ if (matcher.find()) {
+ productSn = matcher.group();
+ log.info("提取后的货号为:" + productSn);
+ } else {
+ log.info(productSn + "未找到符合格式的货号");
+ }
+ return productSn;
+ }
}
diff --git a/hiver-core/src/main/java/cc/hiver/core/serviceimpl/LogiticsCompanyServiceImpl.java b/hiver-core/src/main/java/cc/hiver/core/serviceimpl/LogiticsCompanyServiceImpl.java
index 3bf7d890..8f4c633a 100644
--- a/hiver-core/src/main/java/cc/hiver/core/serviceimpl/LogiticsCompanyServiceImpl.java
+++ b/hiver-core/src/main/java/cc/hiver/core/serviceimpl/LogiticsCompanyServiceImpl.java
@@ -152,7 +152,7 @@ public class LogiticsCompanyServiceImpl implements LogiticsCompanyService {
Predicate[] arr = new Predicate[list.size()];
cq.where(list.toArray(arr));
- cq.orderBy(cb.desc(root.
get("isOnLine")),cb.asc(root.get("companyName")));
+ cq.orderBy(cb.desc(root.get("isOnLine")),cb.desc(root.get("createTime")),cb.asc(root.get("companyName")));
return null;
}
});
diff --git a/hiver-modules/hiver-base/src/main/java/cc/hiver/base/controller/manage/AuthController.java b/hiver-modules/hiver-base/src/main/java/cc/hiver/base/controller/manage/AuthController.java
index a868eecc..57677274 100644
--- a/hiver-modules/hiver-base/src/main/java/cc/hiver/base/controller/manage/AuthController.java
+++ b/hiver-modules/hiver-base/src/main/java/cc/hiver/base/controller/manage/AuthController.java
@@ -25,8 +25,10 @@ import cc.hiver.mall.entity.ShopUser;
import cc.hiver.mall.invitelog.constant.InviteLogConstant;
import cc.hiver.mall.invitelog.entity.InviteLog;
import cc.hiver.mall.invitelog.service.InviteLogService;
+import cc.hiver.mall.pojo.vo.ShopVo;
import cc.hiver.mall.service.ShopService;
import cc.hiver.mall.service.ShopUserService;
+import cc.hiver.mall.service.mybatis.ProductCategoryService;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.IdUtil;
import io.swagger.annotations.Api;
@@ -95,6 +97,8 @@ public class AuthController {
@Autowired
private ShopUserService shopUserService;
+ @Autowired
+ private ProductCategoryService productCategoryService;
@PersistenceContext
private EntityManager entityManager;
@@ -328,10 +332,10 @@ public class AuthController {
public Result register(@Valid RegisterShopVo registerShopVo) {
// 新增用户表信息
User user = new User();
- if(StringUtils.isEmpty(registerShopVo.getMobile())){
+ if (StringUtils.isEmpty(registerShopVo.getMobile())) {
return ResultUtil.error("手机号不能为空!");
}
- if(StringUtils.isEmpty(registerShopVo.getPassword())){
+ if (StringUtils.isEmpty(registerShopVo.getPassword())) {
return ResultUtil.error("密码不能为空!");
}
// 一个用户可存在多个店铺
@@ -397,8 +401,8 @@ public class AuthController {
shopUser.setType(UserConstant.SHOP_USER_ADMIN);
shopUserService.save(shopUser);
// 判断是否传递了邀请人及邀请店铺,设置了的话,新增邀请返佣信息
- if(StringUtils.isNotEmpty(registerShopVo.getInviteUserId()) && StringUtils.isNotEmpty(registerShopVo.getInviteShopId())){
- InviteLog inviteLog = new InviteLog();
+ if (StringUtils.isNotEmpty(registerShopVo.getInviteUserId()) && StringUtils.isNotEmpty(registerShopVo.getInviteShopId())) {
+ final InviteLog inviteLog = new InviteLog();
inviteLog.setInviteUserId(registerShopVo.getInviteUserId());
inviteLog.setInviteShopId(registerShopVo.getInviteShopId());
inviteLog.setRegisterShopId(shop.getId());
@@ -407,6 +411,8 @@ public class AuthController {
inviteLog.setIsOpen(InviteLogConstant.IS_OPEN[0]);
inviteLogService.saveInviteLog(inviteLog);
}
+ // 20240525 新增店铺,默认新增默认分类,颜色-均色;尺码-均码
+ productCategoryService.addShopDefaultCategory(shop.getId());
return ResultUtil.data(user);
}
@@ -425,7 +431,11 @@ public class AuthController {
// 获取店铺的商圈
final Shop shop = shopService.get(shopId);
securityUtil.chooseShop(shopId, shop.getRegionId(), token);
- return ResultUtil.success("成功选择商铺");
+ final ShopVo shopVo = new ShopVo();
+ shopVo.setShopIcon(shop.getShopIcon());
+ shopVo.setShopAddress(shop.getShopAddress());
+ shopVo.setRemark(shop.getRemark());
+ return new ResultUtil().setData(shopVo);
}
/*
@@ -453,20 +463,21 @@ public class AuthController {
/**
* 物流公司注销登录
- * @author 王富康
- * @date 2024/2/25
+ *
* @param companyId
* @param companyName
* @param response
* @return Result
+ * @author 王富康
+ * @date 2024/2/25
*/
- @RequestMapping(value = "/loginOutOfCompany", method = RequestMethod.POST)
+ @RequestMapping(value = "/loginOutOfCompany", method = RequestMethod.POST)
@ApiOperation("物流公司注销登录")
- public Result loginOutOfCompany(String companyId,String companyName, HttpServletResponse response){
- if(StringUtils.isEmpty(companyId)){
+ public Result loginOutOfCompany(String companyId, String companyName, HttpServletResponse response) {
+ if (StringUtils.isEmpty(companyId)) {
return ResultUtil.error("配送公司id不能为空!");
}
- if(StringUtils.isEmpty(companyName)){
+ if (StringUtils.isEmpty(companyName)) {
return ResultUtil.error("配送公司名称不能为空!");
}
final String key = SecurityConstant.COMPANY_TOKEN + companyId + ':' + companyName;
diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/config/thread/AiPurchaseThread.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/config/thread/AiPurchaseThread.java
index f41ba809..ff413929 100644
--- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/config/thread/AiPurchaseThread.java
+++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/config/thread/AiPurchaseThread.java
@@ -4,6 +4,7 @@ import cc.hiver.mall.common.constant.PurchaseConstant;
import cc.hiver.mall.purchaseocr.entity.PurchaseOcrPicture;
import cc.hiver.mall.purchaseocr.service.PurchaseOcrPictureService;
import cc.hiver.mall.purchaseocr.vo.PurchaseOcrExample;
+import cc.hiver.mall.service.mybatis.ProductCategoryService;
import cc.hiver.mall.service.mybatis.ProductService;
import cc.hiver.mall.service.mybatis.PurchaseDetailService;
import cc.hiver.mall.service.mybatis.PurchaseService;
@@ -31,11 +32,12 @@ public class AiPurchaseThread implements Runnable {
private PurchaseDetailService purchaseDetailService;
private PurchaseOcrPicture purchaseOcrPicture;
private PurchaseOcrExample purchaseOcrExample;
+ private ProductCategoryService productCategoryService;
public AiPurchaseThread() {
}
- public AiPurchaseThread(String purchaseId, PurchaseOcrPicture purchaseOcrPicture,PurchaseOcrExample purchaseOcrExample, PurchaseOcrPictureService purchaseOcrPictureService, ProductService productService, PurchaseDetailService purchaseDetailService, PurchaseService purchaseService) {
+ public AiPurchaseThread(String purchaseId, PurchaseOcrPicture purchaseOcrPicture,PurchaseOcrExample purchaseOcrExample, PurchaseOcrPictureService purchaseOcrPictureService, ProductService productService, PurchaseDetailService purchaseDetailService, PurchaseService purchaseService,ProductCategoryService productCategoryService) {
this.purchaseId = purchaseId;
this.purchaseOcrPicture = purchaseOcrPicture;
this.purchaseOcrExample = purchaseOcrExample;
@@ -43,6 +45,7 @@ public class AiPurchaseThread implements Runnable {
this.productService = productService;
this.purchaseDetailService = purchaseDetailService;
this.purchaseService = purchaseService;
+ this.productCategoryService = productCategoryService;
}
public static class Result {
@@ -69,7 +72,7 @@ public class AiPurchaseThread implements Runnable {
log.info("当前线程名称:------------>>>>>" + Thread.currentThread().getName());
try {
log.info("正在ocr识别:" + purchaseOcrPicture.getOcrPicture() + "
线程池名称:" + Thread.currentThread().getName());
- jsonObject = AliOcrUtil.multiRoundConversationCall(purchaseOcrPicture,purchaseOcrExample, productService, purchaseDetailService);
+ jsonObject = AliOcrUtil.multiRoundConversationCall(purchaseOcrPicture,purchaseOcrExample, productService, purchaseDetailService, productCategoryService);
// 得到处理结果之后,开始新增库存的详细信息
purchaseOcrPicture.setOcrMsg(jsonObject.getString("resultContent"));
purchaseOcrPicture.setOcrStatus(PurchaseConstant.OCR_STATUS[1]);
diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/SaleController.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/SaleController.java
index 1a275f9c..086033bb 100644
--- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/SaleController.java
+++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/SaleController.java
@@ -31,7 +31,6 @@ import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
-import org.apache.http.client.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
@@ -493,8 +492,10 @@ public class SaleController {
if (saleVO == null) {
saleVO = new SaleVO();
}
- startTime = saleVO.getStartTime() == null ? DateUtils.formatDate(new Date(), "yyyy-MM-dd") : saleVO.getStartTime();
- endTime = saleVO.getEndTime() == null ? DateUtils.formatDate(new Date(), "yyyy-MM-dd") : saleVO.getEndTime();
+ final String dateText = DateUtil.COMMON.getDateText(new Date());
+ startTime = saleVO.getStartTime() == null ? dateText : saleVO.getStartTime();
+ final String tommorwText = DateUtil.getAfterDayTime(dateText, 1);
+ endTime = saleVO.getEndTime() == null ? tommorwText : saleVO.getEndTime();
saleAllVO = salesCalculateService.calculateService(startTime, endTime);
// 获取本周营收统计
@@ -809,7 +810,7 @@ public class SaleController {
orderService.update(orderXd);
// 库存退回去
// 封装退货的信息
- List returnDetails = new ArrayList<>();
+ final List returnDetails = new ArrayList<>();
final QueryWrapper queryWrapper = new QueryWrapper<>();
queryWrapper.select("product_id")
.eq("sale_id", orderId)
diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/dao/mapper/ProductCategoryMapper.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/dao/mapper/ProductCategoryMapper.java
index ea90d19a..c780b81b 100644
--- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/dao/mapper/ProductCategoryMapper.java
+++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/dao/mapper/ProductCategoryMapper.java
@@ -35,4 +35,5 @@ public interface ProductCategoryMapper extends BaseMapper {
List selectByShopId(String shopId);
List selectByCategoryIdList(@Param("categoryIdList") List categoryIdList);
+
}
\ No newline at end of file
diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/PurchaseDetail.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/PurchaseDetail.java
index ad77f18a..235fa59e 100644
--- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/PurchaseDetail.java
+++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/PurchaseDetail.java
@@ -36,6 +36,11 @@ public class PurchaseDetail extends HiverBaseEntity {
@ApiModelProperty(value = "商品分类")
private String categoryId;
+ @Transient
+ @TableField(exist = false)
+ @ApiModelProperty(value = "分类名称")
+ private String categoryName;
+
@ApiModelProperty(value = "商品属性列表")
private String attributeList;
diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/Sale.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/Sale.java
index 064091df..920ac134 100644
--- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/Sale.java
+++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/Sale.java
@@ -77,6 +77,9 @@ public class Sale implements Serializable {
@ApiModelProperty(value = "收款状态 0-未收款 1-已收款 2-部分收款")
private String payStatus;
+ @ApiModelProperty(value = " 收款方式:0 现金 1微信 2支付宝 3银行卡转账 4收款码")
+ private String payType;
+
/**
* 订单状态开单
* 0:待抢单
diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/pojo/vo/SaleCopyVO.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/pojo/vo/SaleCopyVO.java
index ae79c0cf..5408c65d 100644
--- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/pojo/vo/SaleCopyVO.java
+++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/pojo/vo/SaleCopyVO.java
@@ -1,12 +1,9 @@
package cc.hiver.mall.pojo.vo;
-import cc.hiver.core.common.utils.SnowFlakeUtil;
-import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
-import org.springframework.data.annotation.CreatedDate;
import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable;
@@ -57,6 +54,9 @@ public class SaleCopyVO implements Serializable {
@ApiModelProperty(value = "收款状态 0-未收款 1-已收款 2-部分收款")
private String payStatus;
+ @ApiModelProperty(value = " 收款方式:0 现金 1微信 2支付宝 3银行卡转账 4收款码")
+ private String payType;
+
@ApiModelProperty(value = "订单状态 1-拣货中 2-已预定 3-已作废 4-已取货 5-已送达")
private String status;
diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/pojo/vo/SaleVO.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/pojo/vo/SaleVO.java
index 88a4b13c..ec5f27f9 100644
--- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/pojo/vo/SaleVO.java
+++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/pojo/vo/SaleVO.java
@@ -17,6 +17,9 @@ public class SaleVO implements Serializable {
@ApiModelProperty(value = "收款状态 0-未收款 1-已收款 2-部分收款")
private String payStatus;
+ @ApiModelProperty(value = " 收款方式:0 现金 1微信 2支付宝 3银行卡转账 4收款码")
+ private String payType;
+
@ApiModelProperty(value = "订单状态 1-未预定 2-已预定 3-待自提 4-已取货 5-已送达")
private String status;
diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/pojo/vo/ShopVo.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/pojo/vo/ShopVo.java
new file mode 100644
index 00000000..4d7a3d8e
--- /dev/null
+++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/pojo/vo/ShopVo.java
@@ -0,0 +1,28 @@
+package cc.hiver.mall.pojo.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+/**
+ * 选择店铺之后返回一些店铺信息
+ * @author 王富康
+ * @date 2024/5/23
+ */
+@Data
+@Accessors(chain = true)
+public class ShopVo implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @ApiModelProperty(value = "店铺图标")
+ private String shopIcon;
+
+ @ApiModelProperty(value = "地址")
+ private String shopAddress;
+
+ @ApiModelProperty(value = "备注")
+ private String remark;
+}
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 b10740ce..5fafb518 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
@@ -34,21 +34,36 @@ public class PurchaseOcrPictureController {
@RequestMapping(value = "/batchSave", method = RequestMethod.POST)
@ApiOperation("新增或编辑OCR识别信息")
public Result batchSave(@RequestBody PurchaseOciPictureAddVo purchaseOciPictureAddVo) {
- JSONObject jsonObject = purchaseOcrPictureService.batchSave(purchaseOciPictureAddVo);
+ final JSONObject jsonObject = purchaseOcrPictureService.batchSave(purchaseOciPictureAddVo);
+ return new ResultUtil().setData(jsonObject);
+ }
+
+ /**
+ * Ai语音入库,获取商品信息
+ *
+ * @param questionMsg
+ * @return Result
+ * @author 王富康
+ * @date 2024/5/23
+ */
+ @RequestMapping(value = "/callWithMessageOfPurchase", method = RequestMethod.POST)
+ @ApiOperation("AI语音入库")
+ public Result callWithMessageOfPurchase(String questionMsg) throws NoApiKeyException, InputRequiredException {
+ final JSONObject jsonObject = purchaseOcrPictureService.callWithMessageOfPurchase(questionMsg);
return new ResultUtil().setData(jsonObject);
}
@RequestMapping(value = "/invoicingAi", method = RequestMethod.POST)
@ApiOperation("AI开单")
public Result invoicingAi(String questionMsg) throws NoApiKeyException, InputRequiredException {
- JSONObject jsonObject = purchaseOcrPictureService.invoicingAi(questionMsg);
+ final JSONObject jsonObject = purchaseOcrPictureService.invoicingAi(questionMsg);
return new ResultUtil().setData(jsonObject);
}
@RequestMapping(value = "/multiRoundConversationCall", method = RequestMethod.POST)
@ApiOperation("图片识别-多轮对话")
- public List multiRoundConversationCall(String picturePath,Integer count) throws NoApiKeyException, InputRequiredException, UploadFileException {
- List multiModalConversationResults = purchaseOcrPictureService.multiRoundConversationCall(picturePath,count);
+ public List multiRoundConversationCall(String picturePath, Integer count) throws NoApiKeyException, InputRequiredException, UploadFileException {
+ final List multiModalConversationResults = purchaseOcrPictureService.multiRoundConversationCall(picturePath, count);
return multiModalConversationResults;
}
}
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 7bf5f9ec..98d8cf3d 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
@@ -23,4 +23,6 @@ public interface PurchaseOcrPictureService {
List queryAllPictureStatus(String purchaseId);
List getOcrCount();
+
+ JSONObject callWithMessageOfPurchase(String questionMsg) throws NoApiKeyException, InputRequiredException;
}
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 8426a298..93475611 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
@@ -1,41 +1,55 @@
package cc.hiver.mall.purchaseocr.service.impl;
+import cc.hiver.core.common.utils.CommonUtil;
import cc.hiver.core.common.utils.SecurityUtil;
import cc.hiver.core.entity.User;
import cc.hiver.mall.common.constant.PurchaseConstant;
import cc.hiver.mall.config.thread.AiPurchaseThread;
import cc.hiver.mall.config.thread.ThreadPoolConfiguration;
-import cc.hiver.mall.entity.Purchase;
-import cc.hiver.mall.entity.Shop;
+import cc.hiver.mall.entity.*;
+import cc.hiver.mall.pojo.vo.ProductAttributeOfAddVo;
+import cc.hiver.mall.pojo.vo.ProductAttributeValueVo;
+import cc.hiver.mall.pojo.vo.ProductCategoryVo;
+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.PurchaseOciPictureAddVo;
import cc.hiver.mall.purchaseocr.vo.PurchaseOcrCountVo;
import cc.hiver.mall.purchaseocr.vo.PurchaseOcrExample;
+import cc.hiver.mall.saleaimsg.entity.SaleAiMsg;
import cc.hiver.mall.service.ShopService;
-import cc.hiver.mall.service.mybatis.ProductService;
-import cc.hiver.mall.service.mybatis.PurchaseDetailService;
-import cc.hiver.mall.service.mybatis.PurchaseService;
+import cc.hiver.mall.service.mybatis.*;
import cc.hiver.mall.utils.AliOcrUtil;
+import cn.hutool.core.date.StopWatch;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationResult;
import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.exception.UploadFileException;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
-import java.util.Date;
-import java.util.List;
+import java.math.BigDecimal;
+import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
@Slf4j
@Service
public class PurchaseOcrPictureServiceImpl implements PurchaseOcrPictureService {
+ private static final Pattern productSn = Pattern.compile("货号");
+ private static final Pattern COMPILE = Pattern.compile("\\D+");
+ private static final Pattern SYYS = Pattern.compile("所有颜色", Pattern.LITERAL);
+ private static final Pattern SYCM = Pattern.compile("所有尺码", Pattern.LITERAL);
+
+
@Autowired
private PurchaseOcrPictureMapper purchaseOcrPictureMapper;
@@ -60,6 +74,12 @@ public class PurchaseOcrPictureServiceImpl implements PurchaseOcrPictureService
@Autowired
private ThreadPoolConfiguration threadPoolConfiguration;
+ @Autowired
+ private StockService stockService;
+ @Autowired
+ private ProductCategoryService productCategoryService;
+
+
@Override
public JSONObject batchSave(PurchaseOciPictureAddVo purchaseOciPictureAddVo) {
final JSONObject jsonObject = new JSONObject();
@@ -116,10 +136,10 @@ public class PurchaseOcrPictureServiceImpl implements PurchaseOcrPictureService
// 异步处理ocr识别
try {
// 获取参数示例
- PurchaseOcrExample purchaseOcrExample = purchaseOciPictureAddVo.getPurchaseOcrExample();
+ final PurchaseOcrExample purchaseOcrExample = purchaseOciPictureAddVo.getPurchaseOcrExample();
AiPurchaseThread timerThread;
for (PurchaseOcrPicture purchaseOcrPicture : purchaseOcrPictureAddList) {
- timerThread = new AiPurchaseThread(purchaseId, purchaseOcrPicture,purchaseOcrExample, purchaseOcrPictureService, productService, purchaseDetailService, purchaseService);
+ timerThread = new AiPurchaseThread(purchaseId, purchaseOcrPicture, purchaseOcrExample, purchaseOcrPictureService, productService, purchaseDetailService, purchaseService, productCategoryService);
// 这里可以使用线程池,也可以使用CompletionService处理,运行任务需要是callable的,需要最终结果。
threadPoolConfiguration.threadPoolTaskExecutor().execute(timerThread);
}
@@ -160,4 +180,287 @@ public class PurchaseOcrPictureServiceImpl implements PurchaseOcrPictureService
final String shopId = securityUtil.getShopId();
return purchaseOcrPictureMapper.getOcrCount(shopId);
}
+
+ @Override
+ public JSONObject callWithMessageOfPurchase(String questionMsg) throws NoApiKeyException, InputRequiredException {
+
+ final JSONObject returnJsonObject = new JSONObject();
+ final StopWatch stopWatch = new StopWatch("Ai入库计时:");
+ // 叉转X 文本纠错 使用正则表达式替换单个或多个连续的“叉”字符
+ questionMsg = replaceAllX(questionMsg);
+ // 解析语句,根据“货号”分割换行一下,一个一个执行
+ final String[] split = productSn.split(questionMsg);
+ final List saleAiMsgs = new ArrayList<>();
+ for (String s : split) {
+ if (cc.hiver.core.common.utils.StringUtils.isNotEmpty(s)) {
+ final String oneAiMsg = "货号:" + s;
+ // 封装需要新增的ai开单记录表
+ final SaleAiMsg saleAiMsg = new SaleAiMsg();
+ saleAiMsg.setAiMsg(oneAiMsg);
+ saleAiMsgs.add(saleAiMsg);
+ }
+ }
+ final PurchaseVo purchaseVo = new PurchaseVo();
+ // 定义一个map,货号为key,purchaseDetail 为value
+ final Map purchaseDetailMap = new HashMap<>();
+ // shopId从缓存中设置
+ final String shopId = securityUtil.getShopId();
+ // 进行识别
+ for (SaleAiMsg saleAiMsg : saleAiMsgs) {
+ stopWatch.start("Ai入库计时:" + saleAiMsg);
+ try {
+ final JSONObject jsonObject = AliOcrUtil.callWithMessageOfPurchase(saleAiMsg.getAiMsg());
+ final String resultContent = jsonObject.get("resultContent").toString();
+ final JSONArray json = JSON.parseArray(resultContent);
+
+ for (int i = 0; i < json.size(); i++) {
+ final JSONObject object = json.getJSONObject(i);
+ String productSn = object.getString("productSn");
+ // 尝试从货号中提取正确的货号,因为货号可能包含颜色等信息
+ productSn = CommonUtil.getProductSn(productSn);
+ final String productName = object.getString("productName");
+ final String priceStr = object.getString("price");
+ BigDecimal price = BigDecimal.valueOf(0);
+ // 使用正则表达式提取数字部分
+ final Pattern pattern = Pattern.compile("-?\\d+(\\.\\d+)?");
+ final Matcher matcher = pattern.matcher(priceStr);
+ if (matcher.find()) {
+ // 获取匹配到的数字字符串并转换为BigDecimal
+ final String numericPart = matcher.group();
+ price = new BigDecimal(numericPart);
+
+ }
+
+ final String attributeList = object.getString("attributeList");
+ final JSONArray attributeListJsonArray = JSON.parseArray(attributeList);
+ // 根据货号去查询商品,如果
+ final List byProductSn = productService.getByProductSn(productSn, shopId);
+ if (byProductSn != null && !byProductSn.isEmpty()) {
+ // 原则上一个店铺一个货号对应一个商品,这里如果查到了,直接拿第一个。
+ final Product product = byProductSn.get(0);
+ final String productId = product.getId();
+ // 查询商品所有的库存
+ final List stockList = stockService.getProductStock(productId);
+ final Map stockMap = new HashMap<>();
+ for (Stock stock : stockList) {
+ stockMap.put(stock.getAttributeList(), stock.getStockCount());
+ }
+ final String categoryId = product.getCategoryId();
+ final PurchaseDetail purchaseDetail = new PurchaseDetail();
+ purchaseDetail.setProductId(productId);
+ purchaseDetail.setProductName(product.getProductName());
+ purchaseDetail.setShopId(product.getShopId());
+ purchaseDetail.setCategoryId(categoryId);
+ purchaseDetail.setPrice(product.getPrice());
+ purchaseDetail.setPurchasePrice(price);
+ purchaseDetail.setWholesalePrice(product.getWholesalePrice());
+ purchaseDetail.setProductPicture(product.getProductPicture());
+ purchaseDetail.setProductSn(product.getProductSn());
+ purchaseDetail.setProductCount(0);
+ purchaseDetail.setSupplierName(product.getSupplierName());
+ final List stockLogList = new ArrayList<>();
+
+ // 获取商品分类及规格信息
+ final List categoryIdList = new ArrayList<>();
+ categoryIdList.add(categoryId);
+ final List shopCategory = productCategoryService.getShopCategory(categoryIdList);
+ final ProductCategoryVo productCategoryVo = shopCategory.get(0);
+ final List productAttributeOfAddVos = productCategoryVo.getProductAttributeOfAddVos();
+ final Map productAttributeOfAddVoMap = new HashMap<>();
+ for (ProductAttributeOfAddVo productAttributeOfAddVo : productAttributeOfAddVos) {
+ productAttributeOfAddVoMap.put(productAttributeOfAddVo.getAttributeName(), productAttributeOfAddVo);
+ }
+ //获取颜色及规格进行拼接
+ List colorProductAttributeValueVoList = new ArrayList<>();
+ List sizeProductAttributeValueVoList = new ArrayList<>();
+ if (productAttributeOfAddVoMap.containsKey("颜色")) {
+ colorProductAttributeValueVoList = productAttributeOfAddVoMap.get("颜色").getProductAttributeValueVoList();
+ }
+ // 将所有颜色放到一个集合中
+ final CopyOnWriteArrayList colorList = new CopyOnWriteArrayList<>();
+ for (ProductAttributeValueVo productAttributeValueVo : colorProductAttributeValueVoList) {
+ colorList.add(productAttributeValueVo.getValue());
+ }
+ if (productAttributeOfAddVoMap.containsKey("尺码")) {
+ sizeProductAttributeValueVoList = productAttributeOfAddVoMap.get("尺码").getProductAttributeValueVoList();
+ }
+ // 将所有尺码放到一个集合中
+ final CopyOnWriteArrayList sizeList = new CopyOnWriteArrayList<>();
+ for (ProductAttributeValueVo productAttributeValueVo : sizeProductAttributeValueVoList) {
+ sizeList.add(productAttributeValueVo.getValue());
+ }
+
+ for (int j = 0; j < attributeListJsonArray.size(); j++) {
+ final JSONObject attributeListObject = attributeListJsonArray.getJSONObject(j);
+ String color = attributeListObject.getString("color").toUpperCase();
+ String size = attributeListObject.getString("size").toUpperCase();
+ final String productCount1 = attributeListObject.getString("productCount");
+ final int productCount = Integer.parseInt(COMPILE.matcher(productCount1).replaceAll(""));
+ // 20240330 只能新增颜色和尺码,颜色统一改为*色、尺码统一转大写,加‘码’;
+ // 根据规格id规格是颜色、还是尺码。
+ if (!color.contains("色")) {
+ color += '色';
+ }
+ if (!size.contains("码")) {
+ size += '码';
+ }
+ size = size.toUpperCase();
+
+ if ("SYYS色".equals(color) && "SYCM码".equals(size)) {
+ for (ProductAttributeValueVo productAttributeValueVo : colorProductAttributeValueVoList) {
+ for (ProductAttributeValueVo attributeValueVo : sizeProductAttributeValueVoList) {
+ final StockLog stockLog = new StockLog();
+ final String attribute = "{\"颜色\":\"" + productAttributeValueVo.getValue() + "\",\"尺码\":\"" + attributeValueVo.getValue() + "\"}";
+ stockLog.setAttributeList(attribute);
+ stockLog.setProductCount(productCount);
+ purchaseDetail.setProductCount(purchaseDetail.getProductCount() + productCount);
+ stockLogList.add(stockLog);
+ }
+ }
+ continue;
+ // 所有颜色,所有尺码
+ }
+ if ("SYYS色".equals(color)) {
+ // 所有颜色,固定尺码
+ for (ProductAttributeValueVo productAttributeValueVo : colorProductAttributeValueVoList) {
+ final StockLog stockLog = new StockLog();
+ final String attribute = "{\"颜色\":\"" + productAttributeValueVo.getValue() + "\",\"尺码\":\"" + size + "\"}";
+ stockLog.setAttributeList(attribute);
+ stockLog.setProductCount(productCount);
+ purchaseDetail.setProductCount(purchaseDetail.getProductCount() + productCount);
+ stockLogList.add(stockLog);
+ }
+
+ continue;
+ }
+ if ("SYCM码".equals(size)) {
+ // 所有尺码,固定颜色
+ for (ProductAttributeValueVo attributeValueVo : sizeProductAttributeValueVoList) {
+ final StockLog stockLog = new StockLog();
+ final String attribute = "{\"颜色\":\"" + color + "\",\"尺码\":\"" + attributeValueVo.getValue() + "\"}";
+ stockLog.setAttributeList(attribute);
+ stockLog.setProductCount(productCount);
+ purchaseDetail.setProductCount(purchaseDetail.getProductCount() + productCount);
+ stockLogList.add(stockLog);
+ }
+
+ continue;
+ }
+ // 不包含所有按照获取的拼接
+ final StockLog stockLog = new StockLog();
+ final String attribute = "{\"颜色\":\"" + color + "\",\"尺码\":\"" + size + "\"}";
+ stockLog.setAttributeList(attribute);
+ stockLog.setProductCount(productCount);
+ purchaseDetail.setProductCount(purchaseDetail.getProductCount() + productCount);
+ stockLogList.add(stockLog);
+
+ }
+ // 判断是否存在改货号,如果不存在,新增,存在,则追加stockLogList
+ if (purchaseDetailMap.containsKey(productSn)) {
+ final PurchaseDetail addPurchaseDetail = purchaseDetailMap.get(productSn);
+ addPurchaseDetail.getStockLogList1().addAll(stockLogList);
+ } else {
+ purchaseDetail.setStockLogList1(stockLogList);
+ purchaseDetailMap.put(productSn, purchaseDetail);
+ }
+ } else {
+ // 没查到,封装数据,货号为id
+ final PurchaseDetail purchaseDetail = new PurchaseDetail();
+ purchaseDetail.setId(StringUtils.isEmpty(productSn) ? productName : productSn);
+ purchaseDetail.setProductName(productName);
+ purchaseDetail.setProductSn(productSn);
+ purchaseDetail.setPurchasePrice(price);
+ purchaseDetail.setProductCount(0);
+ // 获取默认分类
+ final ProductCategoryVo defaultCategory = productCategoryService.getDefaultCategory(shopId);
+ if (defaultCategory != null) {
+ purchaseDetail.setCategoryId(defaultCategory.getCategoryId());
+ purchaseDetail.setCategoryName(defaultCategory.getCategoryName());
+ }
+ final List stockLogList = new ArrayList<>();
+ for (int j = 0; j < attributeListJsonArray.size(); j++) {
+ final JSONObject attributeListObject = attributeListJsonArray.getJSONObject(j);
+ String color = attributeListObject.getString("color").toUpperCase();
+ String size = attributeListObject.getString("size").toUpperCase();
+ final String productCount1 = attributeListObject.getString("productCount");
+ final int productCount = Integer.parseInt(COMPILE.matcher(productCount1).replaceAll(""));
+ // 20240330 只能新增颜色和尺码,颜色统一改为*色、尺码统一转大写,加‘码’;
+ // 根据规格id规格是颜色、还是尺码。
+ if (!color.contains("色")) {
+ color += '色';
+ }
+ if (!size.contains("码")) {
+ size += '码';
+ }
+ size = size.toUpperCase();
+ // 不包含所有按照获取的拼接
+ final StockLog stockLog = new StockLog();
+ final String attribute = "{\"颜色\":\"" + color + "\",\"尺码\":\"" + size + "\"}";
+ stockLog.setAttributeList(attribute);
+ stockLog.setProductCount(productCount);
+ purchaseDetail.setProductCount(purchaseDetail.getProductCount() + productCount);
+ stockLogList.add(stockLog);
+ }
+ // 判断是否存在改货号,如果不存在,新增,存在,则追加stockLogList
+ if (purchaseDetailMap.containsKey(productSn)) {
+ final PurchaseDetail addPurchaseDetail = purchaseDetailMap.get(productSn);
+ addPurchaseDetail.getStockLogList1().addAll(stockLogList);
+ } else {
+ purchaseDetail.setStockLogList1(stockLogList);
+ purchaseDetailMap.put(productSn, purchaseDetail);
+ }
+ }
+ }
+ } catch (NoApiKeyException e) {
+ throw new RuntimeException(e);
+ } catch (InputRequiredException e) {
+ throw new RuntimeException(e);
+ }
+ stopWatch.stop();
+ }
+ log.info(stopWatch.prettyPrint());
+ final List purchaseDetails = new ArrayList<>();
+ for (Map.Entry stringPurchaseDetailEntry : purchaseDetailMap.entrySet()) {
+ purchaseDetails.add(stringPurchaseDetailEntry.getValue());
+ }
+ purchaseVo.setPurchaseDetails(purchaseDetails);
+ returnJsonObject.put("data", purchaseVo);
+ return returnJsonObject;
+ }
+
+ /**
+ * 使用正则表达式替换输入字符串中连续的“叉”字符为相应数量的“X”字符。
+ *
+ * @param input 待替换的字符串
+ * @return 替换后的字符串
+ */
+ private static String replaceAllX(String input) {
+ // 定义正则表达式
+ final Pattern pattern = Pattern.compile("(叉+)");
+ // 创建匹配器
+ final Matcher matcher = pattern.matcher(input);
+
+ // 用于构建替换后的结果字符串
+ final StringBuffer sb = new StringBuffer();
+ while (matcher.find()) {
+ // 获取匹配到的“叉”字符数
+ final int count = matcher.group(1).length();
+ // 创建一个字符数组,用于存放“X”字符
+ final char[] xs = new char[count];
+ // 填充数组
+ Arrays.fill(xs, 'X');
+ // 将字符数组转换为字符串
+ final String replacement = new String(xs);
+ // 将替换后的字符串添加到结果缓冲区
+ matcher.appendReplacement(sb, replacement);
+ }
+ // 添加剩余未匹配部分到结果缓冲区
+ matcher.appendTail(sb);
+ // 对【所有】进行特殊处理
+ String returnStr = sb.toString();
+ returnStr = SYYS.matcher(returnStr).replaceAll(",SYYS色");
+ returnStr = SYCM.matcher(returnStr).replaceAll(",SYCM码");
+ // 返回最终替换后的字符串
+ return returnStr;
+ }
}
diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/service/mybatis/ProductCategoryService.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/service/mybatis/ProductCategoryService.java
index 8a57248d..eb84b7a7 100644
--- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/service/mybatis/ProductCategoryService.java
+++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/service/mybatis/ProductCategoryService.java
@@ -13,12 +13,33 @@ public interface ProductCategoryService extends IService {
/**
* AI入库的时候新增的分类信息,分类Id肯定是有的
- * @author 王富康
- * @date 2024/3/31
+ *
* @param productCategoryVoList
* @return boolean
+ * @author 王富康
+ * @date 2024/3/31
*/
boolean batchSaveCategoryAndAttributeOfAi(List productCategoryVoList);
CopyOnWriteArrayList getShopCategory(List categoryIdList);
+
+ /**
+ * 注册店铺是新增默认分类
+ *
+ * @param shopId
+ * @author 王富康
+ * @date 2024/5/25
+ */
+ void addShopDefaultCategory(String shopId);
+
+ /**
+ * 获取该店铺的默认分类,如果只有一个分类就返回,如果多个,就返回空
+ *
+ * @return ProductCategory
+ * @author 王富康
+ * @date 2024/5/25
+ */
+ ProductCategoryVo getDefaultCategory(String shopId);
+
+ List getCategoryByCategoryIdList(List categoryIdList);
}
diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/SalesCalculateServiceImpl.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/SalesCalculateServiceImpl.java
index d78ea419..f18a894b 100644
--- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/SalesCalculateServiceImpl.java
+++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/SalesCalculateServiceImpl.java
@@ -2,7 +2,6 @@ package cc.hiver.mall.serviceimpl;
import cc.hiver.core.common.constant.SaleConstant;
import cc.hiver.core.common.utils.SecurityUtil;
-import cc.hiver.core.common.utils.StringUtils;
import cc.hiver.mall.dao.mapper.ReturnSaleMapper;
import cc.hiver.mall.dao.mapper.SaleMapper;
import cc.hiver.mall.entity.ReturnSaleExample;
@@ -58,22 +57,13 @@ public class SalesCalculateServiceImpl implements SalesCalculateService {
// 店铺id从缓存中获取,并放到数据中去
final String shopId = securityUtil.getShopId();
+ // 日期类型
Date startDate = new Date();
Date endDate = new Date();
// 查询日期范围内数据
try{
- if (StringUtils.isEmpty(startTime) || StringUtils.isEmpty(endTime)) {
-
- startTime = DateUtils.formatDate(new Date(), "yyyy-MM-dd") + " 00:00:00";
- endTime = DateUtils.formatDate(new Date(), "yyyy-MM-dd") + " 23:59:59";
- startDate = DateUtil.COMMON_FULL.getTextDate(startTime);
- endDate = DateUtil.COMMON_FULL.getTextDate(endTime);
- } else {
- startDate = DateUtil.COMMON_FULL.getTextDate(startTime + " 00:00:00");
- endDate = DateUtil.COMMON_FULL.getTextDate(endTime + " 23:59:59");
- // 如果根据时间查询,那么结束时间加1天,
- endTime = DateUtil.addDay(endTime, 1);
- }
+ startDate = DateUtil.COMMON.getTextDate(startTime);
+ endDate = DateUtil.COMMON.getTextDate(endTime);
}catch (Exception e){
log.error("日期转换出错!");
}
diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/ProductCategoryServiceImpl.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/ProductCategoryServiceImpl.java
index 9b10a538..7551dab5 100644
--- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/ProductCategoryServiceImpl.java
+++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/ProductCategoryServiceImpl.java
@@ -14,6 +14,8 @@ import cc.hiver.mall.service.mybatis.ProductAttributeValueService;
import cc.hiver.mall.service.mybatis.ProductCategoryService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.jetbrains.annotations.Nullable;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -44,8 +46,14 @@ public class ProductCategoryServiceImpl extends ServiceImpl addProductAttributeValues = new ArrayList<>();
// 获取这些分类下都有哪些规格
final List shopCategory = getShopCategory(categoryIdList);
- final Map> productAttributes =new HashMap<>();
+ final Map> productAttributes = new HashMap<>();
for (ProductCategoryVo productCategoryVo : shopCategory) {
productAttributes.put(productCategoryVo.getCategoryId(), productCategoryVo.getProductAttributeOfAddVos());
}
@@ -132,7 +140,7 @@ public class ProductCategoryServiceImpl extends ServiceImpl attributeValueList = entry.getValue();
// 首先判断是否需要新增规格
- if(!stockAttributeNameList.contains(attributeName)){
+ if (!stockAttributeNameList.contains(attributeName)) {
final ProductAttribute productAttribute = new ProductAttribute();
productAttribute.setCreateTime(new Date());
productAttribute.setCategoryId(categoryId);
@@ -147,12 +155,12 @@ public class ProductCategoryServiceImpl extends ServiceImpl(productCategoryMap.values());
}
+
+
+ @Override
+ public void addShopDefaultCategory(String shopId) {
+ final ProductCategoryVo productCategoryVo = new ProductCategoryVo();
+ productCategoryVo.setShopId(shopId);
+ productCategoryVo.setCategoryName("默认分类");
+
+ final CopyOnWriteArrayList productAttributeOfAddVos = new CopyOnWriteArrayList<>();
+ // 新增颜色
+ final ProductAttributeOfAddVo productAttributeOfAddVo = new ProductAttributeOfAddVo();
+ productAttributeOfAddVo.setAttributeName("颜色");
+ final CopyOnWriteArrayList productAttributeValueVoList = new CopyOnWriteArrayList<>();
+ final ProductAttributeValueVo productAttributeValueVo = new ProductAttributeValueVo();
+ productAttributeValueVo.setValue("均色");
+ productAttributeValueVoList.add(productAttributeValueVo);
+ // 回填到均色到颜色中
+ productAttributeOfAddVo.setProductAttributeValueVoList(productAttributeValueVoList);
+ // 回填到颜色到分类中
+ productAttributeOfAddVos.add(productAttributeOfAddVo);
+ // 新增尺码
+ final ProductAttributeOfAddVo sizeProductAttributeOfAddVo = new ProductAttributeOfAddVo();
+ sizeProductAttributeOfAddVo.setAttributeName("尺码");
+ final CopyOnWriteArrayList sizeProductAttributeValueVoList = new CopyOnWriteArrayList<>();
+ final ProductAttributeValueVo sizeProductAttributeValueVo = new ProductAttributeValueVo();
+ sizeProductAttributeValueVo.setValue("均码");
+ sizeProductAttributeValueVoList.add(sizeProductAttributeValueVo);
+ // 回填均码到尺码中
+ sizeProductAttributeOfAddVo.setProductAttributeValueVoList(sizeProductAttributeValueVoList);
+ // 回填尺码到分类中
+ productAttributeOfAddVos.add(sizeProductAttributeOfAddVo);
+
+ productCategoryVo.setProductAttributeOfAddVos(productAttributeOfAddVos);
+
+ // 批量去新增
+ batchSaveCategoryAndAttribute(productCategoryVo);
+
+ }
+
+ /**
+ * 获取该店铺的默认分类,如果只有一个分类就返回,如果多个或者本来就没分类,就返回空
+ *
+ * @return ProductCategory
+ * @author 王富康
+ * @date 2024/5/25
+ */
+ @Nullable
+ @Override
+ public ProductCategoryVo getDefaultCategory(String shopId) {
+ final List productCategoryVoList = productCategoryMapper.selectByShopId(shopId);
+ if(productCategoryVoList.isEmpty()){
+ return null;
+ }else{
+ if(productCategoryVoList.size() == 1){
+ return productCategoryVoList.get(0);
+ }else{
+ return null;
+ }
+ }
+ }
+
+ @Override
+ public List getCategoryByCategoryIdList(List categoryIdList) {
+ return productCategoryMapper.selectByCategoryIdList(categoryIdList);
+ }
}
diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/PurchaseServiceImpl.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/PurchaseServiceImpl.java
index 7f1de21f..1e51471e 100644
--- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/PurchaseServiceImpl.java
+++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/PurchaseServiceImpl.java
@@ -8,15 +8,13 @@ import cc.hiver.mall.dao.mapper.PurchaseMapper;
import cc.hiver.mall.entity.*;
import cc.hiver.mall.pojo.dto.DebtSupplier;
import cc.hiver.mall.pojo.query.PurchasePageQuery;
+import cc.hiver.mall.pojo.vo.ProductCategoryVo;
import cc.hiver.mall.pojo.vo.PurchaseVo;
import cc.hiver.mall.purchaseocr.entity.PurchaseOcrPicture;
import cc.hiver.mall.purchaseocr.service.PurchaseOcrPictureService;
import cc.hiver.mall.purchaseocr.vo.PurchaseOcrCountVo;
import cc.hiver.mall.service.SupplierService;
-import cc.hiver.mall.service.mybatis.DealingsRecordService;
-import cc.hiver.mall.service.mybatis.PurchaseDetailService;
-import cc.hiver.mall.service.mybatis.PurchaseService;
-import cc.hiver.mall.service.mybatis.StockLogService;
+import cc.hiver.mall.service.mybatis.*;
import cc.hiver.mall.utils.DateUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -25,6 +23,7 @@ import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.*;
+import java.util.stream.Collectors;
@Service
public class PurchaseServiceImpl extends ServiceImpl implements PurchaseService {
@@ -53,6 +52,9 @@ public class PurchaseServiceImpl extends ServiceImpl i
@Autowired
private PurchaseOcrPictureService purchaseOcrPictureService;
+ @Autowired
+ private ProductCategoryService productCategoryService;
+
@Override
public Page getDebtByShopId(PurchasePageQuery purchasePageQuery) {
@@ -317,6 +319,17 @@ public class PurchaseServiceImpl extends ServiceImpl i
}
// 获取商品信息
final List purchaseDetails = purchaseDetailService.getByPurchaseId(id);
+ // 20240525 需要返回分类名称
+ final List categoryIds = purchaseDetails.stream().map(PurchaseDetail::getCategoryId).collect(Collectors.toList());
+ // 根据分类id获取分类名称
+ final List categoryByCategoryIdList = productCategoryService.getCategoryByCategoryIdList(categoryIds);
+ final Map categoryMap = categoryByCategoryIdList.stream().collect(Collectors.toMap(ProductCategoryVo::getCategoryId, ProductCategoryVo::getCategoryName));
+ // 将分类名称封装到采购单明细中
+ purchaseDetails.forEach(purchaseDetail -> {
+ final String categoryId = purchaseDetail.getCategoryId();
+ purchaseDetail.setCategoryName(categoryMap.get(categoryId));
+ });
+
final List removePurchaseDetails = new ArrayList<>();
// 处理数据
diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/SaleServiceImpl.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/SaleServiceImpl.java
index efe535b3..84abd0b3 100644
--- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/SaleServiceImpl.java
+++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/SaleServiceImpl.java
@@ -2,6 +2,7 @@ package cc.hiver.mall.serviceimpl.mybatis;
import cc.hiver.core.common.constant.DealingsRecordConstant;
import cc.hiver.core.common.constant.SaleConstant;
+import cc.hiver.core.common.utils.CommonUtil;
import cc.hiver.core.common.utils.SecurityUtil;
import cc.hiver.core.common.utils.StringUtils;
import cc.hiver.core.common.utils.ThreadPoolUtil;
@@ -583,7 +584,9 @@ public class SaleServiceImpl extends ServiceImpl implements Sa
final JSONArray json = JSON.parseArray(resultContent);
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 List byProductSn = productService.getByProductSn(productSn, shopId);
if (byProductSn != null && !byProductSn.isEmpty()) {
diff --git a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/StockServiceImpl.java b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/StockServiceImpl.java
index 1ae0cdd5..41e13225 100644
--- a/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/StockServiceImpl.java
+++ b/hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/StockServiceImpl.java
@@ -659,6 +659,7 @@ public class StockServiceImpl extends ServiceImpl implements
// Ai已经生成了入库单主表信息
final Purchase purchase = purchaseVo.getPurchase();
+ purchase.setShopId(shopId);
final String purchaseId = purchase.getId();
// 先根据入库单id 删除详情及库存履历表信息
purchaseDetailService.deleteByPurchaseId(purchaseId);
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 5bd4c519..818695c1 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
@@ -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 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 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 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 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 byProductSn = productService.getByProductSn(productSn, shopId);
if (byProductSn != null && !byProductSn.isEmpty()) {
// 原则上一个店铺一个货号对应一个商品,这里如果查到了,直接拿第一个。
diff --git a/hiver-modules/hiver-mall/src/main/resources/mapper/OperatingAreaMapper.xml b/hiver-modules/hiver-mall/src/main/resources/mapper/OperatingAreaMapper.xml
index cf85dd8d..5ba41828 100644
--- a/hiver-modules/hiver-mall/src/main/resources/mapper/OperatingAreaMapper.xml
+++ b/hiver-modules/hiver-mall/src/main/resources/mapper/OperatingAreaMapper.xml
@@ -220,7 +220,7 @@
)
group by t.shipping_method_id, t.shipping_method
- order by s.is_on_line desc,t.shipping_method
+ order by s.is_on_line desc,s.create_time desc, t.shipping_method