Browse Source

功能优化。

cangku
wangfukang 2 years ago
parent
commit
f13315cecf
  1. 3
      hiver-admin/src/main/resources/application.yml
  2. 16
      hiver-admin/test-output/test-report.html
  3. 26
      hiver-core/src/main/java/cc/hiver/core/common/utils/CommonUtil.java
  4. 2
      hiver-core/src/main/java/cc/hiver/core/serviceimpl/LogiticsCompanyServiceImpl.java
  5. 19
      hiver-modules/hiver-base/src/main/java/cc/hiver/base/controller/manage/AuthController.java
  6. 7
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/config/thread/AiPurchaseThread.java
  7. 9
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/controller/SaleController.java
  8. 1
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/dao/mapper/ProductCategoryMapper.java
  9. 5
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/PurchaseDetail.java
  10. 3
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/Sale.java
  11. 6
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/pojo/vo/SaleCopyVO.java
  12. 3
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/pojo/vo/SaleVO.java
  13. 28
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/pojo/vo/ShopVo.java
  14. 21
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/purchaseocr/controller/PurchaseOcrPictureController.java
  15. 2
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/purchaseocr/service/PurchaseOcrPictureService.java
  16. 321
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/purchaseocr/service/impl/PurchaseOcrPictureServiceImpl.java
  17. 25
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/service/mybatis/ProductCategoryService.java
  18. 16
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/SalesCalculateServiceImpl.java
  19. 73
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/ProductCategoryServiceImpl.java
  20. 21
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/PurchaseServiceImpl.java
  21. 5
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/SaleServiceImpl.java
  22. 1
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/StockServiceImpl.java
  23. 90
      hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/utils/AliOcrUtil.java
  24. 2
      hiver-modules/hiver-mall/src/main/resources/mapper/OperatingAreaMapper.xml
  25. 21
      hiver-modules/hiver-mall/src/main/resources/mapper/SaleMapper.xml

3
hiver-admin/src/main/resources/application.yml

@ -314,12 +314,11 @@ ignored:
- /hiver/app/sale/savePresale - /hiver/app/sale/savePresale
- /hiver/app/productShare/getShareList - /hiver/app/productShare/getShareList
- /hiver/app/productAttribute/selectAttributeAndValueByCategoryId - /hiver/app/productAttribute/selectAttributeAndValueByCategoryId
- /hiver/app/stock/productCount
# 选择物流公司 # 选择物流公司
- /hiver/app/logitics/chooseCompany - /hiver/app/logitics/chooseCompany
# # 临时增加 # # 临时增加
- /hiver/purchaseOcrPicture/batchSave
- /hiver/app/purchase/getPurchaseAllDataOfAi
# 限流及黑名单不拦截的路径 # 限流及黑名单不拦截的路径
limitUrls: limitUrls:

16
hiver-admin/test-output/test-report.html

@ -35,7 +35,7 @@
<a href="#"><span class="badge badge-primary">Hiver</span></a> <a href="#"><span class="badge badge-primary">Hiver</span></a>
</li> </li>
<li class="m-r-10"> <li class="m-r-10">
<a href="#"><span class="badge badge-primary">十二月 18, 2023 11:51:47</span></a> <a href="#"><span class="badge badge-primary">五月 29, 2024 14:41:12</span></a>
</li> </li>
</ul> </ul>
</div> </div>
@ -84,7 +84,7 @@
<div class="test-detail"> <div class="test-detail">
<span class="meta text-white badge badge-sm"></span> <span class="meta text-white badge badge-sm"></span>
<p class="name">passTest</p> <p class="name">passTest</p>
<p class="text-sm"><span>11:51:48 上</span> / <span>0.016 secs</span></p> <p class="text-sm"><span>14:41:13 下</span> / <span>0.019 secs</span></p>
</div> </div>
<div class="test-contents d-none"> <div class="test-contents d-none">
<div class="detail-head"> <div class="detail-head">
@ -92,9 +92,9 @@
<div class="info"> <div class="info">
<div class='float-right'><span class='badge badge-default'>#test-id=1</span></div> <div class='float-right'><span class='badge badge-default'>#test-id=1</span></div>
<h5 class="test-status text-pass">passTest</h5> <h5 class="test-status text-pass">passTest</h5>
<span class='badge badge-success'>12.18.2023 11:51:48</span> <span class='badge badge-success'>05.29.2024 14:41:13</span>
<span class='badge badge-danger'>12.18.2023 11:51:48</span> <span class='badge badge-danger'>05.29.2024 14:41:13</span>
<span class='badge badge-default'>0.016 secs</span> <span class='badge badge-default'>0.019 secs</span>
</div> </div>
<div class="m-t-10 m-l-5"></div> <div class="m-t-10 m-l-5"></div>
</div> </div>
@ -104,7 +104,7 @@
<tbody> <tbody>
<tr class="event-row"> <tr class="event-row">
<td><span class="badge log pass-bg">Pass</span></td> <td><span class="badge log pass-bg">Pass</span></td>
<td>11:51:48</td> <td>14:41:13</td>
<td> <td>
Test passed Test passed
</td> </td>
@ -128,13 +128,13 @@
<div class="col-md-3"> <div class="col-md-3">
<div class="card"><div class="card-body"> <div class="card"><div class="card-body">
<p class="m-b-0">Started</p> <p class="m-b-0">Started</p>
<h3>十二月 18, 2023 11:51:47</h3> <h3>五月 29, 2024 14:41:12</h3>
</div></div> </div></div>
</div> </div>
<div class="col-md-3"> <div class="col-md-3">
<div class="card"><div class="card-body"> <div class="card"><div class="card-body">
<p class="m-b-0">Ended</p> <p class="m-b-0">Ended</p>
<h3>十二月 18, 2023 11:51:48</h3> <h3>五月 29, 2024 14:41:13</h3>
</div></div> </div></div>
</div> </div>
<div class="col-md-3"> <div class="col-md-3">

26
hiver-core/src/main/java/cc/hiver/core/common/utils/CommonUtil.java

@ -1,20 +1,24 @@
package cc.hiver.core.common.utils; package cc.hiver.core.common.utils;
import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.IdUtil;
import lombok.extern.slf4j.Slf4j;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/** /**
* 常用工具 * 常用工具
* *
* @author Yazhi Li * @author Yazhi Li
*/ */
@Slf4j
public class CommonUtil { public class CommonUtil {
private CommonUtil() { private CommonUtil() {
throw new IllegalStateException("Utility class"); throw new IllegalStateException("Utility class");
} }
private static SecureRandom random = new SecureRandom(); private static final SecureRandom random = new SecureRandom();
/** /**
* 以UUID重命名 * 以UUID重命名
@ -25,7 +29,7 @@ public class CommonUtil {
public static String renamePic(String fileName) { public static String renamePic(String fileName) {
String extName = ""; String extName = "";
if (fileName.contains(".")) { if (fileName.contains(".")) {
extName = fileName.substring(fileName.lastIndexOf(".")); extName = fileName.substring(fileName.lastIndexOf('.'));
} }
return IdUtil.simpleUUID() + extName; return IdUtil.simpleUUID() + extName;
} }
@ -34,9 +38,9 @@ public class CommonUtil {
* 随机6位数生成 * 随机6位数生成
*/ */
public static String getRandomNum() { public static String getRandomNum() {
int num = random.nextInt(999999); final int num = random.nextInt(999999);
// 不足六位前面补0 // 不足六位前面补0
String str = String.format("%06d", num); final String str = String.format("%06d", num);
return str; return str;
} }
@ -57,4 +61,18 @@ public class CommonUtil {
} }
return flag; 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;
}
} }

2
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()]; Predicate[] arr = new Predicate[list.size()];
cq.where(list.toArray(arr)); cq.where(list.toArray(arr));
cq.orderBy(cb.desc(root.<Integer>get("isOnLine")),cb.asc(root.<String>get("companyName"))); cq.orderBy(cb.desc(root.<Integer>get("isOnLine")),cb.desc(root.<Integer>get("createTime")),cb.asc(root.<String>get("companyName")));
return null; return null;
} }
}); });

19
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.constant.InviteLogConstant;
import cc.hiver.mall.invitelog.entity.InviteLog; import cc.hiver.mall.invitelog.entity.InviteLog;
import cc.hiver.mall.invitelog.service.InviteLogService; 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.ShopService;
import cc.hiver.mall.service.ShopUserService; import cc.hiver.mall.service.ShopUserService;
import cc.hiver.mall.service.mybatis.ProductCategoryService;
import cn.hutool.core.text.CharSequenceUtil; import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.IdUtil;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
@ -95,6 +97,8 @@ public class AuthController {
@Autowired @Autowired
private ShopUserService shopUserService; private ShopUserService shopUserService;
@Autowired
private ProductCategoryService productCategoryService;
@PersistenceContext @PersistenceContext
private EntityManager entityManager; private EntityManager entityManager;
@ -398,7 +402,7 @@ public class AuthController {
shopUserService.save(shopUser); shopUserService.save(shopUser);
// 判断是否传递了邀请人及邀请店铺,设置了的话,新增邀请返佣信息 // 判断是否传递了邀请人及邀请店铺,设置了的话,新增邀请返佣信息
if (StringUtils.isNotEmpty(registerShopVo.getInviteUserId()) && StringUtils.isNotEmpty(registerShopVo.getInviteShopId())) { if (StringUtils.isNotEmpty(registerShopVo.getInviteUserId()) && StringUtils.isNotEmpty(registerShopVo.getInviteShopId())) {
InviteLog inviteLog = new InviteLog(); final InviteLog inviteLog = new InviteLog();
inviteLog.setInviteUserId(registerShopVo.getInviteUserId()); inviteLog.setInviteUserId(registerShopVo.getInviteUserId());
inviteLog.setInviteShopId(registerShopVo.getInviteShopId()); inviteLog.setInviteShopId(registerShopVo.getInviteShopId());
inviteLog.setRegisterShopId(shop.getId()); inviteLog.setRegisterShopId(shop.getId());
@ -407,6 +411,8 @@ public class AuthController {
inviteLog.setIsOpen(InviteLogConstant.IS_OPEN[0]); inviteLog.setIsOpen(InviteLogConstant.IS_OPEN[0]);
inviteLogService.saveInviteLog(inviteLog); inviteLogService.saveInviteLog(inviteLog);
} }
// 20240525 新增店铺,默认新增默认分类,颜色-均色;尺码-均码
productCategoryService.addShopDefaultCategory(shop.getId());
return ResultUtil.data(user); return ResultUtil.data(user);
} }
@ -425,7 +431,11 @@ public class AuthController {
// 获取店铺的商圈 // 获取店铺的商圈
final Shop shop = shopService.get(shopId); final Shop shop = shopService.get(shopId);
securityUtil.chooseShop(shopId, shop.getRegionId(), token); 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<ShopVo>().setData(shopVo);
} }
/* /*
@ -453,12 +463,13 @@ public class AuthController {
/** /**
* 物流公司注销登录 * 物流公司注销登录
* @author 王富康 *
* @date 2024/2/25
* @param companyId * @param companyId
* @param companyName * @param companyName
* @param response * @param response
* @return Result * @return Result
* @author 王富康
* @date 2024/2/25
*/ */
@RequestMapping(value = "/loginOutOfCompany", method = RequestMethod.POST) @RequestMapping(value = "/loginOutOfCompany", method = RequestMethod.POST)
@ApiOperation("物流公司注销登录") @ApiOperation("物流公司注销登录")

7
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.entity.PurchaseOcrPicture;
import cc.hiver.mall.purchaseocr.service.PurchaseOcrPictureService; import cc.hiver.mall.purchaseocr.service.PurchaseOcrPictureService;
import cc.hiver.mall.purchaseocr.vo.PurchaseOcrExample; 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.ProductService;
import cc.hiver.mall.service.mybatis.PurchaseDetailService; import cc.hiver.mall.service.mybatis.PurchaseDetailService;
import cc.hiver.mall.service.mybatis.PurchaseService; import cc.hiver.mall.service.mybatis.PurchaseService;
@ -31,11 +32,12 @@ public class AiPurchaseThread implements Runnable {
private PurchaseDetailService purchaseDetailService; private PurchaseDetailService purchaseDetailService;
private PurchaseOcrPicture purchaseOcrPicture; private PurchaseOcrPicture purchaseOcrPicture;
private PurchaseOcrExample purchaseOcrExample; private PurchaseOcrExample purchaseOcrExample;
private ProductCategoryService productCategoryService;
public AiPurchaseThread() { 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.purchaseId = purchaseId;
this.purchaseOcrPicture = purchaseOcrPicture; this.purchaseOcrPicture = purchaseOcrPicture;
this.purchaseOcrExample = purchaseOcrExample; this.purchaseOcrExample = purchaseOcrExample;
@ -43,6 +45,7 @@ public class AiPurchaseThread implements Runnable {
this.productService = productService; this.productService = productService;
this.purchaseDetailService = purchaseDetailService; this.purchaseDetailService = purchaseDetailService;
this.purchaseService = purchaseService; this.purchaseService = purchaseService;
this.productCategoryService = productCategoryService;
} }
public static class Result { public static class Result {
@ -69,7 +72,7 @@ public class AiPurchaseThread implements Runnable {
log.info("当前线程名称:------------>>>>>" + Thread.currentThread().getName()); log.info("当前线程名称:------------>>>>>" + Thread.currentThread().getName());
try { try {
log.info("正在ocr识别:" + purchaseOcrPicture.getOcrPicture() + "<br/>线程池名称:" + Thread.currentThread().getName()); log.info("正在ocr识别:" + purchaseOcrPicture.getOcrPicture() + "<br/>线程池名称:" + Thread.currentThread().getName());
jsonObject = AliOcrUtil.multiRoundConversationCall(purchaseOcrPicture,purchaseOcrExample, productService, purchaseDetailService); jsonObject = AliOcrUtil.multiRoundConversationCall(purchaseOcrPicture,purchaseOcrExample, productService, purchaseDetailService, productCategoryService);
// 得到处理结果之后,开始新增库存的详细信息 // 得到处理结果之后,开始新增库存的详细信息
purchaseOcrPicture.setOcrMsg(jsonObject.getString("resultContent")); purchaseOcrPicture.setOcrMsg(jsonObject.getString("resultContent"));
purchaseOcrPicture.setOcrStatus(PurchaseConstant.OCR_STATUS[1]); purchaseOcrPicture.setOcrStatus(PurchaseConstant.OCR_STATUS[1]);

9
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 io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
@ -493,8 +492,10 @@ public class SaleController {
if (saleVO == null) { if (saleVO == null) {
saleVO = new SaleVO(); saleVO = new SaleVO();
} }
startTime = saleVO.getStartTime() == null ? DateUtils.formatDate(new Date(), "yyyy-MM-dd") : saleVO.getStartTime(); final String dateText = DateUtil.COMMON.getDateText(new Date());
endTime = saleVO.getEndTime() == null ? DateUtils.formatDate(new Date(), "yyyy-MM-dd") : saleVO.getEndTime(); 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); saleAllVO = salesCalculateService.calculateService(startTime, endTime);
// 获取本周营收统计 // 获取本周营收统计
@ -809,7 +810,7 @@ public class SaleController {
orderService.update(orderXd); orderService.update(orderXd);
// 库存退回去 // 库存退回去
// 封装退货的信息 // 封装退货的信息
List<ReturnSaleDetailDTO> returnDetails = new ArrayList<>(); final List<ReturnSaleDetailDTO> returnDetails = new ArrayList<>();
final QueryWrapper<SaleDetail> queryWrapper = new QueryWrapper<>(); final QueryWrapper<SaleDetail> queryWrapper = new QueryWrapper<>();
queryWrapper.select("product_id") queryWrapper.select("product_id")
.eq("sale_id", orderId) .eq("sale_id", orderId)

1
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/dao/mapper/ProductCategoryMapper.java

@ -35,4 +35,5 @@ public interface ProductCategoryMapper extends BaseMapper<ProductCategory> {
List<ProductCategoryVo> selectByShopId(String shopId); List<ProductCategoryVo> selectByShopId(String shopId);
List<ProductCategoryVo> selectByCategoryIdList(@Param("categoryIdList") List<String> categoryIdList); List<ProductCategoryVo> selectByCategoryIdList(@Param("categoryIdList") List<String> categoryIdList);
} }

5
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/entity/PurchaseDetail.java

@ -36,6 +36,11 @@ public class PurchaseDetail extends HiverBaseEntity {
@ApiModelProperty(value = "商品分类") @ApiModelProperty(value = "商品分类")
private String categoryId; private String categoryId;
@Transient
@TableField(exist = false)
@ApiModelProperty(value = "分类名称")
private String categoryName;
@ApiModelProperty(value = "商品属性列表") @ApiModelProperty(value = "商品属性列表")
private String attributeList; private String attributeList;

3
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-部分收款") @ApiModelProperty(value = "收款状态 0-未收款 1-已收款 2-部分收款")
private String payStatus; private String payStatus;
@ApiModelProperty(value = " 收款方式:0 现金 1微信 2支付宝 3银行卡转账 4收款码")
private String payType;
/** /**
* 订单状态开单 * 订单状态开单
* 0待抢单 * 0待抢单

6
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/pojo/vo/SaleCopyVO.java

@ -1,12 +1,9 @@
package cc.hiver.mall.pojo.vo; 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 com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.format.annotation.DateTimeFormat; import org.springframework.format.annotation.DateTimeFormat;
import java.io.Serializable; import java.io.Serializable;
@ -57,6 +54,9 @@ public class SaleCopyVO implements Serializable {
@ApiModelProperty(value = "收款状态 0-未收款 1-已收款 2-部分收款") @ApiModelProperty(value = "收款状态 0-未收款 1-已收款 2-部分收款")
private String payStatus; private String payStatus;
@ApiModelProperty(value = " 收款方式:0 现金 1微信 2支付宝 3银行卡转账 4收款码")
private String payType;
@ApiModelProperty(value = "订单状态 1-拣货中 2-已预定 3-已作废 4-已取货 5-已送达") @ApiModelProperty(value = "订单状态 1-拣货中 2-已预定 3-已作废 4-已取货 5-已送达")
private String status; private String status;

3
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-部分收款") @ApiModelProperty(value = "收款状态 0-未收款 1-已收款 2-部分收款")
private String payStatus; private String payStatus;
@ApiModelProperty(value = " 收款方式:0 现金 1微信 2支付宝 3银行卡转账 4收款码")
private String payType;
@ApiModelProperty(value = "订单状态 1-未预定 2-已预定 3-待自提 4-已取货 5-已送达") @ApiModelProperty(value = "订单状态 1-未预定 2-已预定 3-待自提 4-已取货 5-已送达")
private String status; private String status;

28
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;
}

21
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) @RequestMapping(value = "/batchSave", method = RequestMethod.POST)
@ApiOperation("新增或编辑OCR识别信息") @ApiOperation("新增或编辑OCR识别信息")
public Result batchSave(@RequestBody PurchaseOciPictureAddVo purchaseOciPictureAddVo) { public Result batchSave(@RequestBody PurchaseOciPictureAddVo purchaseOciPictureAddVo) {
JSONObject jsonObject = purchaseOcrPictureService.batchSave(purchaseOciPictureAddVo); final JSONObject jsonObject = purchaseOcrPictureService.batchSave(purchaseOciPictureAddVo);
return new ResultUtil<JSONObject>().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<JSONObject>().setData(jsonObject); return new ResultUtil<JSONObject>().setData(jsonObject);
} }
@RequestMapping(value = "/invoicingAi", method = RequestMethod.POST) @RequestMapping(value = "/invoicingAi", method = RequestMethod.POST)
@ApiOperation("AI开单") @ApiOperation("AI开单")
public Result invoicingAi(String questionMsg) throws NoApiKeyException, InputRequiredException { public Result invoicingAi(String questionMsg) throws NoApiKeyException, InputRequiredException {
JSONObject jsonObject = purchaseOcrPictureService.invoicingAi(questionMsg); final JSONObject jsonObject = purchaseOcrPictureService.invoicingAi(questionMsg);
return new ResultUtil<JSONObject>().setData(jsonObject); return new ResultUtil<JSONObject>().setData(jsonObject);
} }
@RequestMapping(value = "/multiRoundConversationCall", method = RequestMethod.POST) @RequestMapping(value = "/multiRoundConversationCall", method = RequestMethod.POST)
@ApiOperation("图片识别-多轮对话") @ApiOperation("图片识别-多轮对话")
public List<MultiModalConversationResult> multiRoundConversationCall(String picturePath, Integer count) throws NoApiKeyException, InputRequiredException, UploadFileException { public List<MultiModalConversationResult> multiRoundConversationCall(String picturePath, Integer count) throws NoApiKeyException, InputRequiredException, UploadFileException {
List<MultiModalConversationResult> multiModalConversationResults = purchaseOcrPictureService.multiRoundConversationCall(picturePath,count); final List<MultiModalConversationResult> multiModalConversationResults = purchaseOcrPictureService.multiRoundConversationCall(picturePath, count);
return multiModalConversationResults; return multiModalConversationResults;
} }
} }

2
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/purchaseocr/service/PurchaseOcrPictureService.java

@ -23,4 +23,6 @@ public interface PurchaseOcrPictureService {
List<PurchaseOcrPicture> queryAllPictureStatus(String purchaseId); List<PurchaseOcrPicture> queryAllPictureStatus(String purchaseId);
List<PurchaseOcrCountVo> getOcrCount(); List<PurchaseOcrCountVo> getOcrCount();
JSONObject callWithMessageOfPurchase(String questionMsg) throws NoApiKeyException, InputRequiredException;
} }

321
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; 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.common.utils.SecurityUtil;
import cc.hiver.core.entity.User; import cc.hiver.core.entity.User;
import cc.hiver.mall.common.constant.PurchaseConstant; import cc.hiver.mall.common.constant.PurchaseConstant;
import cc.hiver.mall.config.thread.AiPurchaseThread; import cc.hiver.mall.config.thread.AiPurchaseThread;
import cc.hiver.mall.config.thread.ThreadPoolConfiguration; import cc.hiver.mall.config.thread.ThreadPoolConfiguration;
import cc.hiver.mall.entity.Purchase; import cc.hiver.mall.entity.*;
import cc.hiver.mall.entity.Shop; 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.entity.PurchaseOcrPicture;
import cc.hiver.mall.purchaseocr.mapper.PurchaseOcrPictureMapper; import cc.hiver.mall.purchaseocr.mapper.PurchaseOcrPictureMapper;
import cc.hiver.mall.purchaseocr.service.PurchaseOcrPictureService; import cc.hiver.mall.purchaseocr.service.PurchaseOcrPictureService;
import cc.hiver.mall.purchaseocr.vo.PurchaseOciPictureAddVo; import cc.hiver.mall.purchaseocr.vo.PurchaseOciPictureAddVo;
import cc.hiver.mall.purchaseocr.vo.PurchaseOcrCountVo; import cc.hiver.mall.purchaseocr.vo.PurchaseOcrCountVo;
import cc.hiver.mall.purchaseocr.vo.PurchaseOcrExample; 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.ShopService;
import cc.hiver.mall.service.mybatis.ProductService; import cc.hiver.mall.service.mybatis.*;
import cc.hiver.mall.service.mybatis.PurchaseDetailService;
import cc.hiver.mall.service.mybatis.PurchaseService;
import cc.hiver.mall.utils.AliOcrUtil; import cc.hiver.mall.utils.AliOcrUtil;
import cn.hutool.core.date.StopWatch;
import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationResult; import com.alibaba.dashscope.aigc.multimodalconversation.MultiModalConversationResult;
import com.alibaba.dashscope.exception.InputRequiredException; import com.alibaba.dashscope.exception.InputRequiredException;
import com.alibaba.dashscope.exception.NoApiKeyException; import com.alibaba.dashscope.exception.NoApiKeyException;
import com.alibaba.dashscope.exception.UploadFileException; import com.alibaba.dashscope.exception.UploadFileException;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.Date; import java.math.BigDecimal;
import java.util.List; import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Slf4j @Slf4j
@Service @Service
public class PurchaseOcrPictureServiceImpl implements PurchaseOcrPictureService { 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 @Autowired
private PurchaseOcrPictureMapper purchaseOcrPictureMapper; private PurchaseOcrPictureMapper purchaseOcrPictureMapper;
@ -60,6 +74,12 @@ public class PurchaseOcrPictureServiceImpl implements PurchaseOcrPictureService
@Autowired @Autowired
private ThreadPoolConfiguration threadPoolConfiguration; private ThreadPoolConfiguration threadPoolConfiguration;
@Autowired
private StockService stockService;
@Autowired
private ProductCategoryService productCategoryService;
@Override @Override
public JSONObject batchSave(PurchaseOciPictureAddVo purchaseOciPictureAddVo) { public JSONObject batchSave(PurchaseOciPictureAddVo purchaseOciPictureAddVo) {
final JSONObject jsonObject = new JSONObject(); final JSONObject jsonObject = new JSONObject();
@ -116,10 +136,10 @@ public class PurchaseOcrPictureServiceImpl implements PurchaseOcrPictureService
// 异步处理ocr识别 // 异步处理ocr识别
try { try {
// 获取参数示例 // 获取参数示例
PurchaseOcrExample purchaseOcrExample = purchaseOciPictureAddVo.getPurchaseOcrExample(); final PurchaseOcrExample purchaseOcrExample = purchaseOciPictureAddVo.getPurchaseOcrExample();
AiPurchaseThread timerThread; AiPurchaseThread timerThread;
for (PurchaseOcrPicture purchaseOcrPicture : purchaseOcrPictureAddList) { 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的,需要最终结果。 // 这里可以使用线程池,也可以使用CompletionService处理,运行任务需要是callable的,需要最终结果。
threadPoolConfiguration.threadPoolTaskExecutor().execute(timerThread); threadPoolConfiguration.threadPoolTaskExecutor().execute(timerThread);
} }
@ -160,4 +180,287 @@ public class PurchaseOcrPictureServiceImpl implements PurchaseOcrPictureService
final String shopId = securityUtil.getShopId(); final String shopId = securityUtil.getShopId();
return purchaseOcrPictureMapper.getOcrCount(shopId); 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<SaleAiMsg> 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<String, PurchaseDetail> 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<Product> byProductSn = productService.getByProductSn(productSn, shopId);
if (byProductSn != null && !byProductSn.isEmpty()) {
// 原则上一个店铺一个货号对应一个商品,这里如果查到了,直接拿第一个。
final Product product = byProductSn.get(0);
final String productId = product.getId();
// 查询商品所有的库存
final List<Stock> stockList = stockService.getProductStock(productId);
final Map<String, Integer> 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<StockLog> stockLogList = new ArrayList<>();
// 获取商品分类及规格信息
final List<String> categoryIdList = new ArrayList<>();
categoryIdList.add(categoryId);
final 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<>();
for (ProductAttributeOfAddVo productAttributeOfAddVo : productAttributeOfAddVos) {
productAttributeOfAddVoMap.put(productAttributeOfAddVo.getAttributeName(), productAttributeOfAddVo);
}
//获取颜色及规格进行拼接
List<ProductAttributeValueVo> colorProductAttributeValueVoList = new ArrayList<>();
List<ProductAttributeValueVo> sizeProductAttributeValueVoList = new ArrayList<>();
if (productAttributeOfAddVoMap.containsKey("颜色")) {
colorProductAttributeValueVoList = productAttributeOfAddVoMap.get("颜色").getProductAttributeValueVoList();
}
// 将所有颜色放到一个集合中
final CopyOnWriteArrayList<String> colorList = new CopyOnWriteArrayList<>();
for (ProductAttributeValueVo productAttributeValueVo : colorProductAttributeValueVoList) {
colorList.add(productAttributeValueVo.getValue());
}
if (productAttributeOfAddVoMap.containsKey("尺码")) {
sizeProductAttributeValueVoList = productAttributeOfAddVoMap.get("尺码").getProductAttributeValueVoList();
}
// 将所有尺码放到一个集合中
final CopyOnWriteArrayList<String> 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<StockLog> 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<PurchaseDetail> purchaseDetails = new ArrayList<>();
for (Map.Entry<String, PurchaseDetail> 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;
}
} }

25
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/service/mybatis/ProductCategoryService.java

@ -13,12 +13,33 @@ public interface ProductCategoryService extends IService<ProductCategory> {
/** /**
* AI入库的时候新增的分类信息分类Id肯定是有的 * AI入库的时候新增的分类信息分类Id肯定是有的
* @author 王富康 *
* @date 2024/3/31
* @param productCategoryVoList * @param productCategoryVoList
* @return boolean * @return boolean
* @author 王富康
* @date 2024/3/31
*/ */
boolean batchSaveCategoryAndAttributeOfAi(List<ProductCategoryAiVo> productCategoryVoList); boolean batchSaveCategoryAndAttributeOfAi(List<ProductCategoryAiVo> productCategoryVoList);
CopyOnWriteArrayList<ProductCategoryVo> getShopCategory(List<String> categoryIdList); CopyOnWriteArrayList<ProductCategoryVo> getShopCategory(List<String> categoryIdList);
/**
* 注册店铺是新增默认分类
*
* @param shopId
* @author 王富康
* @date 2024/5/25
*/
void addShopDefaultCategory(String shopId);
/**
* 获取该店铺的默认分类如果只有一个分类就返回如果多个就返回空
*
* @return ProductCategory
* @author 王富康
* @date 2024/5/25
*/
ProductCategoryVo getDefaultCategory(String shopId);
List<ProductCategoryVo> getCategoryByCategoryIdList(List<String> categoryIdList);
} }

16
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.constant.SaleConstant;
import cc.hiver.core.common.utils.SecurityUtil; 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.ReturnSaleMapper;
import cc.hiver.mall.dao.mapper.SaleMapper; import cc.hiver.mall.dao.mapper.SaleMapper;
import cc.hiver.mall.entity.ReturnSaleExample; import cc.hiver.mall.entity.ReturnSaleExample;
@ -58,22 +57,13 @@ public class SalesCalculateServiceImpl implements SalesCalculateService {
// 店铺id从缓存中获取,并放到数据中去 // 店铺id从缓存中获取,并放到数据中去
final String shopId = securityUtil.getShopId(); final String shopId = securityUtil.getShopId();
// 日期类型
Date startDate = new Date(); Date startDate = new Date();
Date endDate = new Date(); Date endDate = new Date();
// 查询日期范围内数据 // 查询日期范围内数据
try{ try{
if (StringUtils.isEmpty(startTime) || StringUtils.isEmpty(endTime)) { startDate = DateUtil.COMMON.getTextDate(startTime);
endDate = DateUtil.COMMON.getTextDate(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);
}
}catch (Exception e){ }catch (Exception e){
log.error("日期转换出错!"); log.error("日期转换出错!");
} }

73
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 cc.hiver.mall.service.mybatis.ProductCategoryService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j; 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.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -44,8 +46,14 @@ public class ProductCategoryServiceImpl extends ServiceImpl<ProductCategoryMappe
try { try {
// 新增类别信息 // 新增类别信息
final ProductCategory productCategory = new ProductCategory(); final ProductCategory productCategory = new ProductCategory();
// 20240525 注册店铺的时候需要增加默认分类,shopId从注册店铺的那边传过来
if (StringUtils.isEmpty(productCategoryVo.getShopId())) {
final String shopId = securityUtil.getShopId(); final String shopId = securityUtil.getShopId();
productCategory.setShopId(shopId); productCategory.setShopId(shopId);
} else {
productCategory.setShopId(productCategoryVo.getShopId());
}
productCategory.setCategoryName(productCategoryVo.getCategoryName()); productCategory.setCategoryName(productCategoryVo.getCategoryName());
productCategoryMapper.insert(productCategory); productCategoryMapper.insert(productCategory);
@ -248,4 +256,69 @@ public class ProductCategoryServiceImpl extends ServiceImpl<ProductCategoryMappe
} }
return new CopyOnWriteArrayList<>(productCategoryMap.values()); return new CopyOnWriteArrayList<>(productCategoryMap.values());
} }
@Override
public void addShopDefaultCategory(String shopId) {
final ProductCategoryVo productCategoryVo = new ProductCategoryVo();
productCategoryVo.setShopId(shopId);
productCategoryVo.setCategoryName("默认分类");
final CopyOnWriteArrayList<ProductAttributeOfAddVo> productAttributeOfAddVos = new CopyOnWriteArrayList<>();
// 新增颜色
final ProductAttributeOfAddVo productAttributeOfAddVo = new ProductAttributeOfAddVo();
productAttributeOfAddVo.setAttributeName("颜色");
final CopyOnWriteArrayList<ProductAttributeValueVo> 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<ProductAttributeValueVo> 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<ProductCategoryVo> productCategoryVoList = productCategoryMapper.selectByShopId(shopId);
if(productCategoryVoList.isEmpty()){
return null;
}else{
if(productCategoryVoList.size() == 1){
return productCategoryVoList.get(0);
}else{
return null;
}
}
}
@Override
public List<ProductCategoryVo> getCategoryByCategoryIdList(List<String> categoryIdList) {
return productCategoryMapper.selectByCategoryIdList(categoryIdList);
}
} }

21
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.entity.*;
import cc.hiver.mall.pojo.dto.DebtSupplier; import cc.hiver.mall.pojo.dto.DebtSupplier;
import cc.hiver.mall.pojo.query.PurchasePageQuery; 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.pojo.vo.PurchaseVo;
import cc.hiver.mall.purchaseocr.entity.PurchaseOcrPicture; import cc.hiver.mall.purchaseocr.entity.PurchaseOcrPicture;
import cc.hiver.mall.purchaseocr.service.PurchaseOcrPictureService; import cc.hiver.mall.purchaseocr.service.PurchaseOcrPictureService;
import cc.hiver.mall.purchaseocr.vo.PurchaseOcrCountVo; import cc.hiver.mall.purchaseocr.vo.PurchaseOcrCountVo;
import cc.hiver.mall.service.SupplierService; import cc.hiver.mall.service.SupplierService;
import cc.hiver.mall.service.mybatis.DealingsRecordService; import cc.hiver.mall.service.mybatis.*;
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.utils.DateUtil; import cc.hiver.mall.utils.DateUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@ -25,6 +23,7 @@ import org.springframework.stereotype.Service;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.*; import java.util.*;
import java.util.stream.Collectors;
@Service @Service
public class PurchaseServiceImpl extends ServiceImpl<PurchaseMapper, Purchase> implements PurchaseService { public class PurchaseServiceImpl extends ServiceImpl<PurchaseMapper, Purchase> implements PurchaseService {
@ -53,6 +52,9 @@ public class PurchaseServiceImpl extends ServiceImpl<PurchaseMapper, Purchase> i
@Autowired @Autowired
private PurchaseOcrPictureService purchaseOcrPictureService; private PurchaseOcrPictureService purchaseOcrPictureService;
@Autowired
private ProductCategoryService productCategoryService;
@Override @Override
public Page<DebtSupplier> getDebtByShopId(PurchasePageQuery purchasePageQuery) { public Page<DebtSupplier> getDebtByShopId(PurchasePageQuery purchasePageQuery) {
@ -317,6 +319,17 @@ public class PurchaseServiceImpl extends ServiceImpl<PurchaseMapper, Purchase> i
} }
// 获取商品信息 // 获取商品信息
final List<PurchaseDetail> purchaseDetails = purchaseDetailService.getByPurchaseId(id); final List<PurchaseDetail> purchaseDetails = purchaseDetailService.getByPurchaseId(id);
// 20240525 需要返回分类名称
final List<String> categoryIds = purchaseDetails.stream().map(PurchaseDetail::getCategoryId).collect(Collectors.toList());
// 根据分类id获取分类名称
final List<ProductCategoryVo> categoryByCategoryIdList = productCategoryService.getCategoryByCategoryIdList(categoryIds);
final Map<String,String> 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<PurchaseDetail> removePurchaseDetails = new ArrayList<>(); final List<PurchaseDetail> removePurchaseDetails = new ArrayList<>();
// 处理数据 // 处理数据

5
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.DealingsRecordConstant;
import cc.hiver.core.common.constant.SaleConstant; 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.SecurityUtil;
import cc.hiver.core.common.utils.StringUtils; import cc.hiver.core.common.utils.StringUtils;
import cc.hiver.core.common.utils.ThreadPoolUtil; import cc.hiver.core.common.utils.ThreadPoolUtil;
@ -583,7 +584,9 @@ public class SaleServiceImpl extends ServiceImpl<SaleMapper, Sale> implements Sa
final JSONArray json = JSON.parseArray(resultContent); final JSONArray json = JSON.parseArray(resultContent);
for (int i = 0; i < json.size(); i++) { for (int i = 0; i < json.size(); i++) {
final JSONObject object = json.getJSONObject(i); final JSONObject object = json.getJSONObject(i);
final String productSn = object.getString("productSn"); String productSn = object.getString("productSn");
// 尝试从货号中提取正确的货号,因为货号可能包含颜色等信息
productSn = CommonUtil.getProductSn(productSn);
// 根据货号去查询商品,如果 // 根据货号去查询商品,如果
final List<Product> byProductSn = productService.getByProductSn(productSn, shopId); final List<Product> byProductSn = productService.getByProductSn(productSn, shopId);
if (byProductSn != null && !byProductSn.isEmpty()) { if (byProductSn != null && !byProductSn.isEmpty()) {

1
hiver-modules/hiver-mall/src/main/java/cc/hiver/mall/serviceimpl/mybatis/StockServiceImpl.java

@ -659,6 +659,7 @@ public class StockServiceImpl extends ServiceImpl<StockMapper, Stock> implements
// Ai已经生成了入库单主表信息 // Ai已经生成了入库单主表信息
final Purchase purchase = purchaseVo.getPurchase(); final Purchase purchase = purchaseVo.getPurchase();
purchase.setShopId(shopId);
final String purchaseId = purchase.getId(); final String purchaseId = purchase.getId();
// 先根据入库单id 删除详情及库存履历表信息 // 先根据入库单id 删除详情及库存履历表信息
purchaseDetailService.deleteByPurchaseId(purchaseId); purchaseDetailService.deleteByPurchaseId(purchaseId);

90
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. package cc.hiver.mall.utils;// Copyright (c) Alibaba, Inc. and its affiliates.
import cc.hiver.core.common.constant.CommonConstant; 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.config.aliocr.AliOcrConfig;
import cc.hiver.mall.entity.*; import cc.hiver.mall.entity.*;
import cc.hiver.mall.pojo.vo.*; import cc.hiver.mall.pojo.vo.*;
@ -59,7 +60,7 @@ public class AliOcrUtil {
* @author 王富康 * @author 王富康
* @date 2024/3/31 * @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 JSONObject jsonObject = new JSONObject();
final String ocrPictureId = purchaseOcrPicture.getId(); final String ocrPictureId = purchaseOcrPicture.getId();
final String picturePath = purchaseOcrPicture.getOcrPicture(); final String picturePath = purchaseOcrPicture.getOcrPicture();
@ -408,7 +409,7 @@ public class AliOcrUtil {
/*if (StringUtils.isNotEmpty(parentPicturePath)) { /*if (StringUtils.isNotEmpty(parentPicturePath)) {
picturePath = parentPicturePath; picturePath = parentPicturePath;
}*/ }*/
getPurchaseDetailMap(purchaseDetailService, productService, orderId, shopId, picturePath, endJson); getPurchaseDetailMap(purchaseDetailService, productService, orderId, shopId, picturePath, endJson, productCategoryService);
stopWatch.stop(); stopWatch.stop();
// 将map 转为list 进行落库操作 // 将map 转为list 进行落库操作
/*stopWatch.start("批量插入=="); /*stopWatch.start("批量插入==");
@ -487,7 +488,7 @@ public class AliOcrUtil {
* @author 王富康 * @author 王富康
* @date 2024/5/10 * @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 { throws ApiException, NoApiKeyException, UploadFileException {
final JSONObject jsonObject = new JSONObject(); final JSONObject jsonObject = new JSONObject();
final String picturePath = purchaseOcrPicture.getOcrPicture(); final String picturePath = purchaseOcrPicture.getOcrPicture();
@ -574,7 +575,7 @@ public class AliOcrUtil {
/*if (StringUtils.isNotEmpty(parentPicturePath)) { /*if (StringUtils.isNotEmpty(parentPicturePath)) {
picturePath = parentPicturePath; picturePath = parentPicturePath;
}*/ }*/
getPurchaseDetailMap(purchaseDetailService, productService, orderId, shopId, picturePath, json); getPurchaseDetailMap(purchaseDetailService, productService, orderId, shopId, picturePath, json, productCategoryService);
stopWatch.stop(); stopWatch.stop();
log.info(stopWatch.prettyPrint()); log.info(stopWatch.prettyPrint());
@ -597,7 +598,7 @@ public class AliOcrUtil {
* @author 王富康 * @author 王富康
* @date 2024/3/31 * @date 2024/3/31
*/ */
private static void getPurchaseDetailMap(PurchaseDetailService purchaseDetailService, ProductService productService, String orderId, String shopId, String ocrPicturePath, JSONArray json) { private static void getPurchaseDetailMap(PurchaseDetailService purchaseDetailService, ProductService productService, String orderId, String shopId, String ocrPicturePath, JSONArray json, ProductCategoryService productCategoryService) {
// 开始解析图片识别的数据,进行入库操作。 // 开始解析图片识别的数据,进行入库操作。
// 解析未实体对象 // 解析未实体对象
final CopyOnWriteArrayList<PurchaseOcrVo> purchaseOcrVos = new CopyOnWriteArrayList<>(); final CopyOnWriteArrayList<PurchaseOcrVo> purchaseOcrVos = new CopyOnWriteArrayList<>();
@ -608,7 +609,10 @@ public class AliOcrUtil {
for (int i = 0; i < json.size(); i++) { for (int i = 0; i < json.size(); i++) {
final JSONObject jsonObject = json.getJSONObject(i); final JSONObject jsonObject = json.getJSONObject(i);
final PurchaseOcrVo purchaseOcrVo = new PurchaseOcrVo(); 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.setProductName(jsonObject.getString("productName"));
purchaseOcrVo.setPrice(jsonObject.getBigDecimal("price")); purchaseOcrVo.setPrice(jsonObject.getBigDecimal("price"));
final String productCount = jsonObject.getString("productCount"); final String productCount = jsonObject.getString("productCount");
@ -794,6 +798,12 @@ public class AliOcrUtil {
purchaseDetail.setWholesalePrice(product.getWholesalePrice()); purchaseDetail.setWholesalePrice(product.getWholesalePrice());
purchaseDetail.setProductName(product.getProductName()); purchaseDetail.setProductName(product.getProductName());
stockLog.setProductId(product.getId()); stockLog.setProductId(product.getId());
}else{
// 新商品,获取默认分类
final ProductCategoryVo defaultCategory = productCategoryService.getDefaultCategory(shopId);
if (defaultCategory != null) {
purchaseDetail.setCategoryId(defaultCategory.getCategoryId());
}
} }
stockLogList.add(stockLog); stockLogList.add(stockLog);
purchaseDetail.setStockLogList1(stockLogList); purchaseDetail.setStockLogList1(stockLogList);
@ -822,7 +832,11 @@ public class AliOcrUtil {
final MessageManager msgManager = new MessageManager(10); final MessageManager msgManager = new MessageManager(10);
final Message systemMsg = final Message systemMsg =
Message.builder().role(Role.SYSTEM.getValue()).content("You are a helpful assistant.").build(); 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(); final Message userMsg = Message.builder().role(Role.USER.getValue()).content(questionMsg).build();
msgManager.add(systemMsg); msgManager.add(systemMsg);
msgManager.add(userMsg); msgManager.add(userMsg);
@ -830,10 +844,6 @@ public class AliOcrUtil {
final QwenParam param = final QwenParam param =
QwenParam.builder().model(Generation.Models.QWEN_PLUS).messages(msgManager.get()) QwenParam.builder().model(Generation.Models.QWEN_PLUS).messages(msgManager.get())
.resultFormat(QwenParam.ResultFormat.MESSAGE) .resultFormat(QwenParam.ResultFormat.MESSAGE)
.temperature(1F)
.topP(0.1)
.topK(1)
.seed(500)
.build(); .build();
final GenerationResult result = gen.call(param); final GenerationResult result = gen.call(param);
log.info(result.toString()); log.info(result.toString());
@ -850,6 +860,48 @@ public class AliOcrUtil {
return jsonObject; 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) public static JSONObject callWithMessageSync(String questionMsg, String saleId, String shopId, String createBy, ProductService productService, ProductCategoryService productCategoryService, SaleService saleService, SaleDetailService saleDetailService)
throws NoApiKeyException, ApiException, InputRequiredException { throws NoApiKeyException, ApiException, InputRequiredException {
final JSONObject jsonObject = new JSONObject(); final JSONObject jsonObject = new JSONObject();
@ -859,7 +911,11 @@ public class AliOcrUtil {
final MessageManager msgManager = new MessageManager(10); final MessageManager msgManager = new MessageManager(10);
final Message systemMsg = final Message systemMsg =
Message.builder().role(Role.SYSTEM.getValue()).content("You are a helpful assistant.").build(); 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(); final Message userMsg = Message.builder().role(Role.USER.getValue()).content(questionMsg).build();
msgManager.add(systemMsg); msgManager.add(systemMsg);
msgManager.add(userMsg); msgManager.add(userMsg);
@ -867,10 +923,6 @@ public class AliOcrUtil {
final QwenParam param = final QwenParam param =
QwenParam.builder().model(Generation.Models.QWEN_PLUS).messages(msgManager.get()) QwenParam.builder().model(Generation.Models.QWEN_PLUS).messages(msgManager.get())
.resultFormat(QwenParam.ResultFormat.MESSAGE) .resultFormat(QwenParam.ResultFormat.MESSAGE)
.temperature(1F)
.topP(0.1)
.topK(1)
.seed(500)
.build(); .build();
final GenerationResult result = gen.call(param); final GenerationResult result = gen.call(param);
log.info(result.toString()); log.info(result.toString());
@ -911,8 +963,10 @@ public class AliOcrUtil {
final CopyOnWriteArrayList<SaleDetail> saleDetailList = new CopyOnWriteArrayList<>(); final CopyOnWriteArrayList<SaleDetail> saleDetailList = new CopyOnWriteArrayList<>();
for (int i = 0; i < json.size(); i++) { for (int i = 0; i < json.size(); i++) {
final JSONObject object = json.getJSONObject(i); final JSONObject object = json.getJSONObject(i);
final String productSn = object.getString("productSn"); String productSn = object.getString("productSn");
// 根据货号去查询商品,如果 // 尝试从货号中提取正确的货号,因为货号可能包含颜色等信息
productSn = CommonUtil.getProductSn(productSn);
// 根据货号去查询商品
final CopyOnWriteArrayList<Product> byProductSn = productService.getByProductSn(productSn, shopId); final CopyOnWriteArrayList<Product> byProductSn = productService.getByProductSn(productSn, shopId);
if (byProductSn != null && !byProductSn.isEmpty()) { if (byProductSn != null && !byProductSn.isEmpty()) {
// 原则上一个店铺一个货号对应一个商品,这里如果查到了,直接拿第一个。 // 原则上一个店铺一个货号对应一个商品,这里如果查到了,直接拿第一个。

2
hiver-modules/hiver-mall/src/main/resources/mapper/OperatingAreaMapper.xml

@ -220,7 +220,7 @@
) )
</if> </if>
group by t.shipping_method_id, t.shipping_method 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
</select> </select>
<!--管理商品分页列表--> <!--管理商品分页列表-->
<select id="getOperatingAreaList" resultType="cc.hiver.mall.operatingarea.vo.OperatingAreaPageVO"> <select id="getOperatingAreaList" resultType="cc.hiver.mall.operatingarea.vo.OperatingAreaPageVO">

21
hiver-modules/hiver-mall/src/main/resources/mapper/SaleMapper.xml

@ -21,6 +21,7 @@
<result column="already_earn" jdbcType="DECIMAL" property="alreadyEarn" /> <result column="already_earn" jdbcType="DECIMAL" property="alreadyEarn" />
<result column="no_earn" jdbcType="DECIMAL" property="noEarn" /> <result column="no_earn" jdbcType="DECIMAL" property="noEarn" />
<result column="pay_status" jdbcType="VARCHAR" property="payStatus" /> <result column="pay_status" jdbcType="VARCHAR" property="payStatus" />
<result column="pay_type" jdbcType="VARCHAR" property="payType" />
<result column="status" jdbcType="VARCHAR" property="status" /> <result column="status" jdbcType="VARCHAR" property="status" />
<result column="transport_type" jdbcType="VARCHAR" property="transportType" /> <result column="transport_type" jdbcType="VARCHAR" property="transportType" />
<result column="share_address" jdbcType="VARCHAR" property="shareAddress" /> <result column="share_address" jdbcType="VARCHAR" property="shareAddress" />
@ -102,7 +103,7 @@
</sql> </sql>
<sql id="Base_Column_List"> <sql id="Base_Column_List">
id, create_by, create_by_name, create_time, del_flag, update_by, update_by_name, update_time, user_id, user_name, shop_id, shop_name, total_amount, discount, id, create_by, create_by_name, create_time, del_flag, update_by, update_by_name, update_time, user_id, user_name, shop_id, shop_name, total_amount, discount,
discount_amount, real_amount, already_earn, no_earn, pay_status, status, other_expense, transport_type, share_address, receive_address, province, city, area, discount_amount, real_amount, already_earn, no_earn, pay_status,pay_type, status, other_expense, transport_type, share_address, receive_address, province, city, area,
trans_company, company_name, product_count, remark, sale_name, company_phone, create_by_phone,mode_of_service,ai_flag,ai_result,ai_not_recognition trans_company, company_name, product_count, remark, sale_name, company_phone, create_by_phone,mode_of_service,ai_flag,ai_result,ai_not_recognition
</sql> </sql>
@ -141,7 +142,7 @@ trans_company, company_name, product_count, remark, sale_name, company_phone, cr
del_flag, update_by,update_by_name, update_time, del_flag, update_by,update_by_name, update_time,
user_id,user_name, shop_id,shop_name, total_amount, user_id,user_name, shop_id,shop_name, total_amount,
discount, discount_amount, real_amount, discount, discount_amount, real_amount,
already_earn, no_earn, pay_status, already_earn, no_earn, pay_status,pay_type,
status, transport_type, share_address, status, transport_type, share_address,
receive_address, province, city, receive_address, province, city,
area,sale_name,remark,other_expense,trans_company,company_name,company_phone,product_count,create_by_phone,mode_of_service,ai_flag,ai_result,ai_not_recognition) area,sale_name,remark,other_expense,trans_company,company_name,company_phone,product_count,create_by_phone,mode_of_service,ai_flag,ai_result,ai_not_recognition)
@ -149,7 +150,7 @@ trans_company, company_name, product_count, remark, sale_name, company_phone, cr
#{delFlag,jdbcType=INTEGER}, #{updateBy,jdbcType=VARCHAR},#{updateByName,jdbcType=VARCHAR}, #{updateTime,jdbcType=TIMESTAMP}, #{delFlag,jdbcType=INTEGER}, #{updateBy,jdbcType=VARCHAR},#{updateByName,jdbcType=VARCHAR}, #{updateTime,jdbcType=TIMESTAMP},
#{userId,jdbcType=VARCHAR},#{userName,jdbcType=VARCHAR}, #{shopId,jdbcType=VARCHAR},#{shopName,jdbcType=VARCHAR}, #{totalAmount,jdbcType=DECIMAL}, #{userId,jdbcType=VARCHAR},#{userName,jdbcType=VARCHAR}, #{shopId,jdbcType=VARCHAR},#{shopName,jdbcType=VARCHAR}, #{totalAmount,jdbcType=DECIMAL},
#{discount,jdbcType=DECIMAL}, #{discountAmount,jdbcType=DECIMAL}, #{realAmount,jdbcType=DECIMAL}, #{discount,jdbcType=DECIMAL}, #{discountAmount,jdbcType=DECIMAL}, #{realAmount,jdbcType=DECIMAL},
#{alreadyEarn,jdbcType=DECIMAL}, #{noEarn,jdbcType=DECIMAL}, #{payStatus,jdbcType=VARCHAR}, #{alreadyEarn,jdbcType=DECIMAL}, #{noEarn,jdbcType=DECIMAL}, #{payStatus,jdbcType=VARCHAR}, #{payType,jdbcType=VARCHAR},
#{status,jdbcType=VARCHAR}, #{transportType,jdbcType=VARCHAR}, #{shareAddress,jdbcType=VARCHAR}, #{status,jdbcType=VARCHAR}, #{transportType,jdbcType=VARCHAR}, #{shareAddress,jdbcType=VARCHAR},
#{receiveAddress,jdbcType=VARCHAR}, #{province,jdbcType=VARCHAR}, #{city,jdbcType=VARCHAR}, #{receiveAddress,jdbcType=VARCHAR}, #{province,jdbcType=VARCHAR}, #{city,jdbcType=VARCHAR},
#{area,jdbcType=VARCHAR}, #{saleName,jdbcType=VARCHAR}, #{remark,jdbcType=VARCHAR}, #{area,jdbcType=VARCHAR}, #{saleName,jdbcType=VARCHAR}, #{remark,jdbcType=VARCHAR},
@ -208,6 +209,9 @@ trans_company, company_name, product_count, remark, sale_name, company_phone, cr
<if test="payStatus != null"> <if test="payStatus != null">
pay_status, pay_status,
</if> </if>
<if test="payType != null">
pay_type,
</if>
<if test="status != null"> <if test="status != null">
status, status,
</if> </if>
@ -420,6 +424,9 @@ trans_company, company_name, product_count, remark, sale_name, company_phone, cr
<if test="record.payStatus != null"> <if test="record.payStatus != null">
pay_status = #{record.payStatus,jdbcType=VARCHAR}, pay_status = #{record.payStatus,jdbcType=VARCHAR},
</if> </if>
<if test="record.payType != null">
pay_type = #{record.payType,jdbcType=VARCHAR},
</if>
<if test="record.status != null"> <if test="record.status != null">
status = #{record.status,jdbcType=VARCHAR}, status = #{record.status,jdbcType=VARCHAR},
</if> </if>
@ -494,6 +501,7 @@ trans_company, company_name, product_count, remark, sale_name, company_phone, cr
already_earn = #{record.alreadyEarn,jdbcType=DECIMAL}, already_earn = #{record.alreadyEarn,jdbcType=DECIMAL},
no_earn = #{record.noEarn,jdbcType=DECIMAL}, no_earn = #{record.noEarn,jdbcType=DECIMAL},
pay_status = #{record.payStatus,jdbcType=VARCHAR}, pay_status = #{record.payStatus,jdbcType=VARCHAR},
pay_type = #{record.payType,jdbcType=VARCHAR},
status = #{record.status,jdbcType=VARCHAR}, status = #{record.status,jdbcType=VARCHAR},
transport_type = #{record.transportType,jdbcType=VARCHAR}, transport_type = #{record.transportType,jdbcType=VARCHAR},
share_address = #{record.shareAddress,jdbcType=VARCHAR}, share_address = #{record.shareAddress,jdbcType=VARCHAR},
@ -562,6 +570,9 @@ trans_company, company_name, product_count, remark, sale_name, company_phone, cr
</if> </if>
<if test="payStatus != null"> <if test="payStatus != null">
pay_status = #{payStatus,jdbcType=VARCHAR}, pay_status = #{payStatus,jdbcType=VARCHAR},
</if>
<if test="payType != null">
pay_type = #{payType,jdbcType=VARCHAR},
</if> </if>
<if test="status != null"> <if test="status != null">
status = #{status,jdbcType=VARCHAR}, status = #{status,jdbcType=VARCHAR},
@ -634,6 +645,7 @@ trans_company, company_name, product_count, remark, sale_name, company_phone, cr
already_earn = #{alreadyEarn,jdbcType=DECIMAL}, already_earn = #{alreadyEarn,jdbcType=DECIMAL},
no_earn = #{noEarn,jdbcType=DECIMAL}, no_earn = #{noEarn,jdbcType=DECIMAL},
pay_status = #{payStatus,jdbcType=VARCHAR}, pay_status = #{payStatus,jdbcType=VARCHAR},
pay_type = #{payType,jdbcType=VARCHAR},
status = #{status,jdbcType=VARCHAR}, status = #{status,jdbcType=VARCHAR},
transport_type = #{transportType,jdbcType=VARCHAR}, transport_type = #{transportType,jdbcType=VARCHAR},
share_address = #{shareAddress,jdbcType=VARCHAR}, share_address = #{shareAddress,jdbcType=VARCHAR},
@ -747,6 +759,9 @@ trans_company, company_name, product_count, remark, sale_name, company_phone, cr
<if test='saleVO.payStatus!=null'> <if test='saleVO.payStatus!=null'>
and pay_status = #{saleVO.payStatus} and pay_status = #{saleVO.payStatus}
</if> </if>
<if test='saleVO.payType!=null'>
and pay_type = #{saleVO.payType}
</if>
<if test='saleVO.status!=null'> <if test='saleVO.status!=null'>
and status = #{saleVO.status} and status = #{saleVO.status}
</if> </if>

Loading…
Cancel
Save