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. 33
      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. 23
      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. 87
      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. 262
      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;
} }
}); });

33
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;
@ -328,10 +332,10 @@ public class AuthController {
public Result register(@Valid RegisterShopVo registerShopVo) { public Result register(@Valid RegisterShopVo registerShopVo) {
// 新增用户表信息 // 新增用户表信息
User user = new User(); User user = new User();
if(StringUtils.isEmpty(registerShopVo.getMobile())){ if (StringUtils.isEmpty(registerShopVo.getMobile())) {
return ResultUtil.error("手机号不能为空!"); return ResultUtil.error("手机号不能为空!");
} }
if(StringUtils.isEmpty(registerShopVo.getPassword())){ if (StringUtils.isEmpty(registerShopVo.getPassword())) {
return ResultUtil.error("密码不能为空!"); return ResultUtil.error("密码不能为空!");
} }
// 一个用户可存在多个店铺 // 一个用户可存在多个店铺
@ -397,8 +401,8 @@ public class AuthController {
shopUser.setType(UserConstant.SHOP_USER_ADMIN); shopUser.setType(UserConstant.SHOP_USER_ADMIN);
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,20 +463,21 @@ 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("物流公司注销登录")
public Result loginOutOfCompany(String companyId,String companyName, HttpServletResponse response){ public Result loginOutOfCompany(String companyId, String companyName, HttpServletResponse response) {
if(StringUtils.isEmpty(companyId)){ if (StringUtils.isEmpty(companyId)) {
return ResultUtil.error("配送公司id不能为空!"); return ResultUtil.error("配送公司id不能为空!");
} }
if(StringUtils.isEmpty(companyName)){ if (StringUtils.isEmpty(companyName)) {
return ResultUtil.error("配送公司名称不能为空!"); return ResultUtil.error("配送公司名称不能为空!");
} }
final String key = SecurityConstant.COMPANY_TOKEN + companyId + ':' + companyName; final String key = SecurityConstant.COMPANY_TOKEN + companyId + ':' + companyName;

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

23
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("日期转换出错!");
} }

87
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();
final String shopId = securityUtil.getShopId(); // 20240525 注册店铺的时候需要增加默认分类,shopId从注册店铺的那边传过来
productCategory.setShopId(shopId); if (StringUtils.isEmpty(productCategoryVo.getShopId())) {
final String shopId = securityUtil.getShopId();
productCategory.setShopId(shopId);
} else {
productCategory.setShopId(productCategoryVo.getShopId());
}
productCategory.setCategoryName(productCategoryVo.getCategoryName()); productCategory.setCategoryName(productCategoryVo.getCategoryName());
productCategoryMapper.insert(productCategory); productCategoryMapper.insert(productCategory);
@ -114,7 +122,7 @@ public class ProductCategoryServiceImpl extends ServiceImpl<ProductCategoryMappe
final List<ProductAttributeValue> addProductAttributeValues = new ArrayList<>(); final List<ProductAttributeValue> addProductAttributeValues = new ArrayList<>();
// 获取这些分类下都有哪些规格 // 获取这些分类下都有哪些规格
final List<ProductCategoryVo> shopCategory = getShopCategory(categoryIdList); final List<ProductCategoryVo> shopCategory = getShopCategory(categoryIdList);
final Map<String, List<ProductAttributeOfAddVo>> productAttributes =new HashMap<>(); final Map<String, List<ProductAttributeOfAddVo>> productAttributes = new HashMap<>();
for (ProductCategoryVo productCategoryVo : shopCategory) { for (ProductCategoryVo productCategoryVo : shopCategory) {
productAttributes.put(productCategoryVo.getCategoryId(), productCategoryVo.getProductAttributeOfAddVos()); productAttributes.put(productCategoryVo.getCategoryId(), productCategoryVo.getProductAttributeOfAddVos());
} }
@ -132,7 +140,7 @@ public class ProductCategoryServiceImpl extends ServiceImpl<ProductCategoryMappe
final String attributeName = entry.getKey(); final String attributeName = entry.getKey();
final List<String> attributeValueList = entry.getValue(); final List<String> attributeValueList = entry.getValue();
// 首先判断是否需要新增规格 // 首先判断是否需要新增规格
if(!stockAttributeNameList.contains(attributeName)){ if (!stockAttributeNameList.contains(attributeName)) {
final ProductAttribute productAttribute = new ProductAttribute(); final ProductAttribute productAttribute = new ProductAttribute();
productAttribute.setCreateTime(new Date()); productAttribute.setCreateTime(new Date());
productAttribute.setCategoryId(categoryId); productAttribute.setCategoryId(categoryId);
@ -147,12 +155,12 @@ public class ProductCategoryServiceImpl extends ServiceImpl<ProductCategoryMappe
productAttributeValue.setValue(s); productAttributeValue.setValue(s);
addProductAttributeValues.add(productAttributeValue); addProductAttributeValues.add(productAttributeValue);
} }
}else{ } else {
// 包含规格,那么就只需要新增属性即可 // 包含规格,那么就只需要新增属性即可
// 拿到旧的规格 // 拿到旧的规格
ProductAttributeOfAddVo oldProductAttributeOfAddVo = new ProductAttributeOfAddVo(); ProductAttributeOfAddVo oldProductAttributeOfAddVo = new ProductAttributeOfAddVo();
for (ProductAttributeOfAddVo productAttributeOfAddVo : productAttributeOfAddVos) { for (ProductAttributeOfAddVo productAttributeOfAddVo : productAttributeOfAddVos) {
if(productAttributeOfAddVo.getAttributeName().equals(attributeName)){ if (productAttributeOfAddVo.getAttributeName().equals(attributeName)) {
oldProductAttributeOfAddVo = productAttributeOfAddVo; oldProductAttributeOfAddVo = productAttributeOfAddVo;
} }
} }
@ -163,7 +171,7 @@ public class ProductCategoryServiceImpl extends ServiceImpl<ProductCategoryMappe
} }
// 判断旧的值中是否包含新的值,如果不包含就新增 // 判断旧的值中是否包含新的值,如果不包含就新增
for (String s : attributeValueList) { for (String s : attributeValueList) {
if(!stockAttributeValueList.contains(s)){ if (!stockAttributeValueList.contains(s)) {
final ProductAttributeValue productAttributeValue = new ProductAttributeValue(); final ProductAttributeValue productAttributeValue = new ProductAttributeValue();
productAttributeValue.setCreateTime(new Date()); productAttributeValue.setCreateTime(new Date());
productAttributeValue.setAttributeId(oldProductAttributeOfAddVo.getAttributeId()); productAttributeValue.setAttributeId(oldProductAttributeOfAddVo.getAttributeId());
@ -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);

262
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();
@ -71,13 +72,13 @@ public class AliOcrUtil {
// 拼接的示例结果 // 拼接的示例结果
String productSnExample = purchaseOcrExample.getProductSn(); String productSnExample = purchaseOcrExample.getProductSn();
String productNameExample = purchaseOcrExample.getProductName(); String productNameExample = purchaseOcrExample.getProductName();
if(StringUtils.isNotEmpty(ocrPictureOrder)){ if (StringUtils.isNotEmpty(ocrPictureOrder)) {
final String[] strings = ocrPictureOrder.split("-"); final String[] strings = ocrPictureOrder.split("-");
final String indexStr = strings[0]; final String indexStr = strings[0];
productSnExample += indexStr; productSnExample += indexStr;
productNameExample += indexStr; productNameExample += indexStr;
} }
final StopWatch stopWatch = new StopWatch(ocrPictureId+"Ai回答计时"); final StopWatch stopWatch = new StopWatch(ocrPictureId + "Ai回答计时");
Constants.apiKey = "sk-bcfa4865b89548acb8225f910f13d682"; Constants.apiKey = "sk-bcfa4865b89548acb8225f910f13d682";
final CopyOnWriteArrayList<MultiModalConversationResult> multiModalConversationResults = new CopyOnWriteArrayList<>(); final CopyOnWriteArrayList<MultiModalConversationResult> multiModalConversationResults = new CopyOnWriteArrayList<>();
final MultiModalConversation conv = new MultiModalConversation(); final MultiModalConversation conv = new MultiModalConversation();
@ -96,7 +97,7 @@ public class AliOcrUtil {
"5.如果按照你的理解在图中找到了productSn和productName字段对应的信息,则productSn和productName字段的值以图中内容为准。如果按照你的理解在图中没有找到productSn和productName字段对应的信息,则productSn和productName字段的值使用JSON示例中productSn和productName的值填充。 " + "5.如果按照你的理解在图中找到了productSn和productName字段对应的信息,则productSn和productName字段的值以图中内容为准。如果按照你的理解在图中没有找到productSn和productName字段对应的信息,则productSn和productName字段的值使用JSON示例中productSn和productName的值填充。 " +
"6.请注意返回JSON符号解析格式正确 ,确保java程序能够正确解析。" + "6.请注意返回JSON符号解析格式正确 ,确保java程序能够正确解析。" +
"7.严格返回" + count + "条JSON数据,如果数量有偏差按照实际条数返回,不能自动省略!"; "7.严格返回" + count + "条JSON数据,如果数量有偏差按照实际条数返回,不能自动省略!";
log.info("AI提问内容:"+firstQuestionMsg); log.info("AI提问内容:" + firstQuestionMsg);
MultiModalMessageItemText userText = new MultiModalMessageItemText(firstQuestionMsg); MultiModalMessageItemText userText = new MultiModalMessageItemText(firstQuestionMsg);
final MultiModalConversationMessage userMessage = final MultiModalConversationMessage userMessage =
MultiModalConversationMessage.builder().role(Role.USER.getValue()) MultiModalConversationMessage.builder().role(Role.USER.getValue())
@ -114,7 +115,7 @@ public class AliOcrUtil {
multiModalConversationResults.add(result); multiModalConversationResults.add(result);
// 解析结果 // 解析结果
String text = result.getOutput().getChoices().get(0).getMessage().getContent().get(0).get("text").toString(); 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 startIndex = text.indexOf('{');
final int endIndex = text.lastIndexOf('}'); final int endIndex = text.lastIndexOf('}');
@ -127,45 +128,45 @@ public class AliOcrUtil {
// 有时候返回的是productCounts,改为productCount // 有时候返回的是productCounts,改为productCount
jsonStr = fixJsonStr(jsonStr); jsonStr = fixJsonStr(jsonStr);
JSONArray endJson = new JSONArray(); JSONArray endJson = new JSONArray();
try{ try {
endJson = JSON.parseArray(jsonStr); endJson = JSON.parseArray(jsonStr);
}catch (Exception e){ } catch (Exception e) {
log.error(Thread.currentThread().getName()+"-一轮对话--->json识别报错喽,没关系,我把错误信息输出出来:"+e.getMessage(), e); log.error(Thread.currentThread().getName() + "-一轮对话--->json识别报错喽,没关系,我把错误信息输出出来:" + e.getMessage(), e);
// 如果格式化报错,特殊处理下,再次进行转义。 // 如果格式化报错,特殊处理下,再次进行转义。
final String message = e.getMessage(); final String message = e.getMessage();
boolean needAgain = true; boolean needAgain = true;
// 以下是对目前可能出现的问题进行过滤处理 // 以下是对目前可能出现的问题进行过滤处理
// attributeList格式不对 // attributeList格式不对
if(message.contains("attributeList")){ if (message.contains("attributeList")) {
needAgain = false; needAgain = false;
log.error(Thread.currentThread().getName()+"-一轮对话--->json识别报错喽,没关系,attributeList格式有问题,我来替换一下!"); log.error(Thread.currentThread().getName() + "-一轮对话--->json识别报错喽,没关系,attributeList格式有问题,我来替换一下!");
// 如果是attributeList出现问题,那么尝试修复。 // 如果是attributeList出现问题,那么尝试修复。
jsonStr = fixAttributeList(jsonStr); jsonStr = fixAttributeList(jsonStr);
try{ try {
endJson = JSON.parseArray(jsonStr); endJson = JSON.parseArray(jsonStr);
}catch (Exception replaceOneException){ } catch (Exception replaceOneException) {
log.error(Thread.currentThread().getName()+"-一轮对话--->json识别报错喽,没关系,attributeList替换了也没好使!"); log.error(Thread.currentThread().getName() + "-一轮对话--->json识别报错喽,没关系,attributeList替换了也没好使!");
needAgain = true; needAgain = true;
} }
} }
// 识别多了个“}” // 识别多了个“}”
if(message.contains("not close endJson text")){ if (message.contains("not close endJson text")) {
needAgain = false; needAgain = false;
log.error(Thread.currentThread().getName()+"-一轮对话--->json识别报错喽,没关系,可能是多了“}”,我来去掉试一下一下!"); log.error(Thread.currentThread().getName() + "-一轮对话--->json识别报错喽,没关系,可能是多了“}”,我来去掉试一下一下!");
// //
jsonStr = jsonStr.substring(0, jsonStr.length()-1); jsonStr = jsonStr.substring(0, jsonStr.length() - 1);
try{ try {
endJson = JSON.parseArray(jsonStr); endJson = JSON.parseArray(jsonStr);
}catch (Exception replaceOneException){ } catch (Exception replaceOneException) {
log.error(Thread.currentThread().getName()+"-一轮对话--->json识别报错喽,没关系,可能是多了“}”,去掉了也没好使!"); log.error(Thread.currentThread().getName() + "-一轮对话--->json识别报错喽,没关系,可能是多了“}”,去掉了也没好使!");
needAgain = true; needAgain = true;
} }
} }
if(needAgain){ if (needAgain) {
log.error(Thread.currentThread().getName()+"-一轮对话--->json识别报错喽,没关系,我来重新识别一下!"); log.error(Thread.currentThread().getName() + "-一轮对话--->json识别报错喽,没关系,我来重新识别一下!");
//尝试重新识别一次 //尝试重新识别一次
final String errorJsonQuestionMsg = "返回的json格式有误,请重新返回。"; final String errorJsonQuestionMsg = "返回的json格式有误,请重新返回。";
final MultiModalMessageItemText assistentText = new MultiModalMessageItemText( final MultiModalMessageItemText assistentText = new MultiModalMessageItemText(
@ -183,7 +184,7 @@ public class AliOcrUtil {
stopWatch.stop(); stopWatch.stop();
// 解析结果 // 解析结果
text = result.getOutput().getChoices().get(0).getMessage().getContent().get(0).get("text").toString(); 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 secondStartIndex = text.indexOf('{');
final int secondEndIndex = text.lastIndexOf('}'); final int secondEndIndex = text.lastIndexOf('}');
@ -192,43 +193,43 @@ public class AliOcrUtil {
// 有时候返回的是productCounts,改为productCount // 有时候返回的是productCounts,改为productCount
errorJsonJsonStr = fixJsonStr(errorJsonJsonStr); errorJsonJsonStr = fixJsonStr(errorJsonJsonStr);
try{ try {
// //
endJson = JSON.parseArray(errorJsonJsonStr); endJson = JSON.parseArray(errorJsonJsonStr);
}catch (Exception errorJsonException){ } catch (Exception errorJsonException) {
log.error(Thread.currentThread().getName()+"-一轮对话--->json识别报错喽,重新识别又报错了,没关系,我把错误信息输出出来:"+errorJsonException.getMessage(), errorJsonException); log.error(Thread.currentThread().getName() + "-一轮对话--->json识别报错喽,重新识别又报错了,没关系,我把错误信息输出出来:" + errorJsonException.getMessage(), errorJsonException);
// 如果格式化报错,特殊处理下,再次进行转义。 // 如果格式化报错,特殊处理下,再次进行转义。
final String errorJsonExceptionMessage = errorJsonException.getMessage(); final String errorJsonExceptionMessage = errorJsonException.getMessage();
boolean firstCheckResult = true; boolean firstCheckResult = true;
if(errorJsonExceptionMessage.contains("attributeList")){ if (errorJsonExceptionMessage.contains("attributeList")) {
firstCheckResult = false; firstCheckResult = false;
log.error(Thread.currentThread().getName()+"-一轮对话--->json识别报错喽,重新识别又报错了,没关系,attributeList格式有问题,我来替换一下!"); log.error(Thread.currentThread().getName() + "-一轮对话--->json识别报错喽,重新识别又报错了,没关系,attributeList格式有问题,我来替换一下!");
// 如果是attributeList出现问题,那么尝试修复。 // 如果是attributeList出现问题,那么尝试修复。
errorJsonJsonStr = fixAttributeList(errorJsonJsonStr); errorJsonJsonStr = fixAttributeList(errorJsonJsonStr);
try{ try {
endJson = JSON.parseArray(errorJsonJsonStr); endJson = JSON.parseArray(errorJsonJsonStr);
}catch (Exception errorJsonJsonException){ } catch (Exception errorJsonJsonException) {
log.error(Thread.currentThread().getName()+"-一轮对话--->json识别报错喽,重新识别又报错了,attributeList替换了也没好使!"); log.error(Thread.currentThread().getName() + "-一轮对话--->json识别报错喽,重新识别又报错了,attributeList替换了也没好使!");
firstCheckResult = true; firstCheckResult = true;
} }
} }
// 识别多了个“}” // 识别多了个“}”
if(errorJsonExceptionMessage.contains("not close endJson text")){ if (errorJsonExceptionMessage.contains("not close endJson text")) {
firstCheckResult = false; firstCheckResult = false;
log.error(Thread.currentThread().getName()+"-一轮对话--->json识别报错喽,重新识别又报错了,没关系,可能是多了“}”,我来去掉试一下一下!"); log.error(Thread.currentThread().getName() + "-一轮对话--->json识别报错喽,重新识别又报错了,没关系,可能是多了“}”,我来去掉试一下一下!");
// //
errorJsonJsonStr = errorJsonJsonStr.substring(0, errorJsonJsonStr.length()-1); errorJsonJsonStr = errorJsonJsonStr.substring(0, errorJsonJsonStr.length() - 1);
try{ try {
endJson = JSON.parseArray(errorJsonJsonStr); endJson = JSON.parseArray(errorJsonJsonStr);
}catch (Exception replaceOneException){ } catch (Exception replaceOneException) {
log.error(Thread.currentThread().getName()+"-一轮对话--->json识别报错喽,重新识别又报错了,可能是多了“}”,去掉了也没好使!"); log.error(Thread.currentThread().getName() + "-一轮对话--->json识别报错喽,重新识别又报错了,可能是多了“}”,去掉了也没好使!");
firstCheckResult = true; firstCheckResult = true;
} }
} }
if(firstCheckResult){ if (firstCheckResult) {
log.error(Thread.currentThread().getName()+"-一轮对话--->json识别报错喽,,重新识别又报错了,不识别了,直接毁灭吧!"); log.error(Thread.currentThread().getName() + "-一轮对话--->json识别报错喽,,重新识别又报错了,不识别了,直接毁灭吧!");
throw errorJsonException; throw errorJsonException;
} }
} }
@ -255,69 +256,69 @@ public class AliOcrUtil {
stopWatch.stop(); stopWatch.stop();
// 解析结果 // 解析结果
String secondText = result.getOutput().getChoices().get(0).getMessage().getContent().get(0).get("text").toString(); 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 secondStartIndex = secondText.indexOf('{');
final int secondEndIndex = secondText.lastIndexOf('}'); final int secondEndIndex = secondText.lastIndexOf('}');
if (secondStartIndex == -1 || secondEndIndex == -1) { if (secondStartIndex == -1 || secondEndIndex == -1) {
// 二轮对话,没有查询到想要的数据,那么就使用一轮的结果 // 二轮对话,没有查询到想要的数据,那么就使用一轮的结果
log.info(Thread.currentThread().getName()+"-二轮对话--->识别数据失败,使用第一次的识别结果未找到指定标识符:识别结果为:" + text); log.info(Thread.currentThread().getName() + "-二轮对话--->识别数据失败,使用第一次的识别结果未找到指定标识符:识别结果为:" + text);
}else{ } else {
String secondJsonStr = '[' + secondText.substring(secondStartIndex, secondEndIndex + 1) + ']'; String secondJsonStr = '[' + secondText.substring(secondStartIndex, secondEndIndex + 1) + ']';
// 有时候返回的是productCounts,改为productCount // 有时候返回的是productCounts,改为productCount
secondJsonStr = fixJsonStr(secondJsonStr); secondJsonStr = fixJsonStr(secondJsonStr);
try{ try {
final JSONArray secondJson = JSON.parseArray(secondJsonStr); final JSONArray secondJson = JSON.parseArray(secondJsonStr);
final int secondResultCount = secondJson.size(); final int secondResultCount = secondJson.size();
// 20240515 跟第一次的数据对比,哪个数量多,用哪个。 // 20240515 跟第一次的数据对比,哪个数量多,用哪个。
if(secondResultCount > fristResultCount){ if (secondResultCount > fristResultCount) {
endJson = secondJson; endJson = secondJson;
} }
}catch (Exception e){ } catch (Exception e) {
boolean needAgain = true; 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(); final String message = e.getMessage();
if(message.contains("attributeList")){ if (message.contains("attributeList")) {
needAgain = false; needAgain = false;
log.error(Thread.currentThread().getName()+"-二轮对话--->json识别报错喽,没关系,attributeList格式有问题,我来替换一下!"); log.error(Thread.currentThread().getName() + "-二轮对话--->json识别报错喽,没关系,attributeList格式有问题,我来替换一下!");
// 如果是attributeList出现问题,那么尝试修复。 // 如果是attributeList出现问题,那么尝试修复。
secondJsonStr = fixAttributeList(secondJsonStr); secondJsonStr = fixAttributeList(secondJsonStr);
try{ try {
// endJson = JSON.parseArray(secondJsonStr); // endJson = JSON.parseArray(secondJsonStr);
final JSONArray secondJson = JSON.parseArray(secondJsonStr); final JSONArray secondJson = JSON.parseArray(secondJsonStr);
final int secondResultCount = secondJson.size(); final int secondResultCount = secondJson.size();
// 20240515 跟第一次的数据对比,哪个数量多,用哪个。 // 20240515 跟第一次的数据对比,哪个数量多,用哪个。
if(secondResultCount > fristResultCount){ if (secondResultCount > fristResultCount) {
endJson = secondJson; endJson = secondJson;
} }
}catch (Exception exception){ } catch (Exception exception) {
log.error(Thread.currentThread().getName()+"-二轮对话--->json识别报错喽,attributeList替换了也没好使!"); log.error(Thread.currentThread().getName() + "-二轮对话--->json识别报错喽,attributeList替换了也没好使!");
needAgain = true; needAgain = true;
} }
} }
// 识别多了个“}” // 识别多了个“}”
if(message.contains("not close endJson text")){ if (message.contains("not close endJson text")) {
needAgain = false; needAgain = false;
log.error(Thread.currentThread().getName()+"-二轮对话--->json识别报错喽,没关系,可能是多了“}”,我来去掉试一下一下!"); log.error(Thread.currentThread().getName() + "-二轮对话--->json识别报错喽,没关系,可能是多了“}”,我来去掉试一下一下!");
// //
secondJsonStr = secondJsonStr.substring(0, secondJsonStr.length()-1); secondJsonStr = secondJsonStr.substring(0, secondJsonStr.length() - 1);
try{ try {
// endJson = JSON.parseArray(secondJsonStr); // endJson = JSON.parseArray(secondJsonStr);
final JSONArray secondJson = JSON.parseArray(secondJsonStr); final JSONArray secondJson = JSON.parseArray(secondJsonStr);
final int secondResultCount = secondJson.size(); final int secondResultCount = secondJson.size();
// 20240515 跟第一次的数据对比,哪个数量多,用哪个。 // 20240515 跟第一次的数据对比,哪个数量多,用哪个。
if(secondResultCount > fristResultCount){ if (secondResultCount > fristResultCount) {
endJson = secondJson; endJson = secondJson;
} }
}catch (Exception replaceOneException){ } catch (Exception replaceOneException) {
log.error(Thread.currentThread().getName()+"-二轮对话--->json识别报错喽,可能是多了“}”,去掉了也没好使!"); log.error(Thread.currentThread().getName() + "-二轮对话--->json识别报错喽,可能是多了“}”,去掉了也没好使!");
needAgain = true; needAgain = true;
} }
} }
if(needAgain){ if (needAgain) {
log.error(Thread.currentThread().getName()+"-二轮对话--->json识别报错喽,没关系,我来重新识别一下!"); log.error(Thread.currentThread().getName() + "-二轮对话--->json识别报错喽,没关系,我来重新识别一下!");
//尝试重新识别一次 //尝试重新识别一次
final String errorJsonQuestionMsg = "返回的json格式有误,请重新返回。"; final String errorJsonQuestionMsg = "返回的json格式有误,请重新返回。";
final MultiModalMessageItemText secondJsonErrorAssistentText = new MultiModalMessageItemText( final MultiModalMessageItemText secondJsonErrorAssistentText = new MultiModalMessageItemText(
@ -335,7 +336,7 @@ public class AliOcrUtil {
stopWatch.stop(); stopWatch.stop();
// 解析结果 // 解析结果
secondText = result.getOutput().getChoices().get(0).getMessage().getContent().get(0).get("text").toString(); 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 errorSsecondStartIndex = secondText.indexOf('{');
final int errorSecondEndIndex = secondText.lastIndexOf('}'); final int errorSecondEndIndex = secondText.lastIndexOf('}');
@ -343,58 +344,58 @@ public class AliOcrUtil {
String errorJsonJsonStr = '[' + secondText.substring(errorSsecondStartIndex, errorSecondEndIndex + 1) + ']'; String errorJsonJsonStr = '[' + secondText.substring(errorSsecondStartIndex, errorSecondEndIndex + 1) + ']';
// 有时候返回的是productCounts,改为productCount // 有时候返回的是productCounts,改为productCount
errorJsonJsonStr = fixJsonStr(errorJsonJsonStr); errorJsonJsonStr = fixJsonStr(errorJsonJsonStr);
try{ try {
// //
// endJson = JSON.parseArray(errorJsonJsonStr); // endJson = JSON.parseArray(errorJsonJsonStr);
final JSONArray secondJson = JSON.parseArray(errorJsonJsonStr); final JSONArray secondJson = JSON.parseArray(errorJsonJsonStr);
final int secondResultCount = secondJson.size(); final int secondResultCount = secondJson.size();
// 20240515 跟第一次的数据对比,哪个数量多,用哪个。 // 20240515 跟第一次的数据对比,哪个数量多,用哪个。
if(secondResultCount > fristResultCount){ if (secondResultCount > fristResultCount) {
endJson = secondJson; endJson = secondJson;
} }
}catch (Exception errorJsonException){ } catch (Exception errorJsonException) {
boolean secondCheckResult = true; boolean secondCheckResult = true;
final String errorJsonExceptionMessage = errorJsonException.getMessage(); final String errorJsonExceptionMessage = errorJsonException.getMessage();
log.error(Thread.currentThread().getName()+"-二轮对话--->json识别报错喽,重新识别又报错了,没关系,我把错误信息输出出来:"+ errorJsonExceptionMessage, errorJsonException); log.error(Thread.currentThread().getName() + "-二轮对话--->json识别报错喽,重新识别又报错了,没关系,我把错误信息输出出来:" + errorJsonExceptionMessage, errorJsonException);
if(errorJsonExceptionMessage.contains("attributeList")){ if (errorJsonExceptionMessage.contains("attributeList")) {
secondCheckResult = false; secondCheckResult = false;
log.error(Thread.currentThread().getName()+"-二轮对话--->json识别报错喽,,重新识别又报错了,没关系,,attributeList格式有问题,我来替换一下!"); log.error(Thread.currentThread().getName() + "-二轮对话--->json识别报错喽,,重新识别又报错了,没关系,,attributeList格式有问题,我来替换一下!");
// 如果是attributeList出现问题,那么尝试修复。 // 如果是attributeList出现问题,那么尝试修复。
errorJsonJsonStr = fixAttributeList(errorJsonJsonStr); errorJsonJsonStr = fixAttributeList(errorJsonJsonStr);
try{ try {
// endJson = JSON.parseArray(errorJsonJsonStr); // endJson = JSON.parseArray(errorJsonJsonStr);
final JSONArray secondJson = JSON.parseArray(errorJsonJsonStr); final JSONArray secondJson = JSON.parseArray(errorJsonJsonStr);
final int secondResultCount = secondJson.size(); final int secondResultCount = secondJson.size();
// 20240515 跟第一次的数据对比,哪个数量多,用哪个。 // 20240515 跟第一次的数据对比,哪个数量多,用哪个。
if(secondResultCount > fristResultCount){ if (secondResultCount > fristResultCount) {
endJson = secondJson; endJson = secondJson;
} }
}catch (Exception secondCheckException){ } catch (Exception secondCheckException) {
log.error(Thread.currentThread().getName()+"-二轮对话--->json识别报错喽,,重新识别又报错了,attributeList替换了也没好使!"); log.error(Thread.currentThread().getName() + "-二轮对话--->json识别报错喽,,重新识别又报错了,attributeList替换了也没好使!");
secondCheckResult = true; secondCheckResult = true;
} }
} }
if(errorJsonExceptionMessage.contains("not close endJson text")){ if (errorJsonExceptionMessage.contains("not close endJson text")) {
secondCheckResult = false; secondCheckResult = false;
log.error(Thread.currentThread().getName()+"-二轮对话--->json识别报错喽,重新识别又报错了,没关系,可能是多了“}”,我来去掉试一下一下!"); log.error(Thread.currentThread().getName() + "-二轮对话--->json识别报错喽,重新识别又报错了,没关系,可能是多了“}”,我来去掉试一下一下!");
// 如果是attributeList出现问题,那么尝试修复。 // 如果是attributeList出现问题,那么尝试修复。
errorJsonJsonStr = errorJsonJsonStr.substring(0, errorJsonJsonStr.length()-1); errorJsonJsonStr = errorJsonJsonStr.substring(0, errorJsonJsonStr.length() - 1);
try{ try {
// endJson = JSON.parseArray(errorJsonJsonStr); // endJson = JSON.parseArray(errorJsonJsonStr);
final JSONArray secondJson = JSON.parseArray(errorJsonJsonStr); final JSONArray secondJson = JSON.parseArray(errorJsonJsonStr);
final int secondResultCount = secondJson.size(); final int secondResultCount = secondJson.size();
// 20240515 跟第一次的数据对比,哪个数量多,用哪个。 // 20240515 跟第一次的数据对比,哪个数量多,用哪个。
if(secondResultCount > fristResultCount){ if (secondResultCount > fristResultCount) {
endJson = secondJson; endJson = secondJson;
} }
}catch (Exception secondCheckException){ } catch (Exception secondCheckException) {
log.error(Thread.currentThread().getName()+"-二轮对话--->json识别报错喽,重新识别又报错了,可能是多了“}”,去掉了也没好使!"); log.error(Thread.currentThread().getName() + "-二轮对话--->json识别报错喽,重新识别又报错了,可能是多了“}”,去掉了也没好使!");
secondCheckResult = true; secondCheckResult = true;
} }
} }
if(secondCheckResult){ if (secondCheckResult) {
log.error(Thread.currentThread().getName()+"-二轮对话--->json识别报错喽,,重新识别又报错了,不识别了,直接用第一次识别的结果吧!"); log.error(Thread.currentThread().getName() + "-二轮对话--->json识别报错喽,,重新识别又报错了,不识别了,直接用第一次识别的结果吧!");
} }
} }
} }
@ -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("批量插入==");
@ -446,7 +447,7 @@ public class AliOcrUtil {
attributeList = attributeList.replace("productCounts", "productCount"); attributeList = attributeList.replace("productCounts", "productCount");
return attributeList; return attributeList;
} }
/** /**
* 1.有时候返回的是productCounts改为productCount * 1.有时候返回的是productCounts改为productCount
* 2. 有的时候中间会有...,需要特殊处理一下 * 2. 有的时候中间会有...,需要特殊处理一下
@ -458,16 +459,16 @@ public class AliOcrUtil {
*/ */
public static String fixJsonStr(String str) { public static String fixJsonStr(String str) {
// 如果包含"...",那么就截取掉,在商品中不会出现,并且在json应该只会出现一次,如果会出现多次的话,那这里需要再次优化 // 如果包含"...",那么就截取掉,在商品中不会出现,并且在json应该只会出现一次,如果会出现多次的话,那这里需要再次优化
if(str.contains("...")){ if (str.contains("...")) {
final String[] newStr = COMPILED.split(str); final String[] newStr = COMPILED.split(str);
final int newStrLength = newStr.length; final int newStrLength = newStr.length;
if(newStrLength ==2){ if (newStrLength == 2) {
// 第一个字符串从开头截取到第一个} // 第一个字符串从开头截取到第一个}
newStr[0] = newStr[0].substring(0, newStr[0].lastIndexOf('}')); newStr[0] = newStr[0].substring(0, newStr[0].lastIndexOf('}'));
// 第二个字符串从第一个{截取到最后 // 第二个字符串从第一个{截取到最后
newStr[1] = newStr[1].substring(newStr[1].indexOf('{')); newStr[1] = newStr[1].substring(newStr[1].indexOf('{'));
// 重新拼接,并且中间加上逗号 // 重新拼接,并且中间加上逗号
str = newStr[0]+ ',' +newStr[1]; str = newStr[0] + ',' + newStr[1];
} }
} }
str = str.replace("productCounts", "productCount"); str = str.replace("productCounts", "productCount");
@ -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");
@ -626,7 +630,7 @@ public class AliOcrUtil {
final CopyOnWriteArrayList<PurchaseOcrDetailVo> attributeList = new CopyOnWriteArrayList<>(); final CopyOnWriteArrayList<PurchaseOcrDetailVo> attributeList = new CopyOnWriteArrayList<>();
final String size = attributeListJson.getString("size"); final String size = attributeListJson.getString("size");
if(size.contains(",")){ if (size.contains(",")) {
final String[] sizeArray = size.split(","); final String[] sizeArray = size.split(",");
for (String s : sizeArray) { for (String s : sizeArray) {
final PurchaseOcrDetailVo purchaseOcrDetailVo = new PurchaseOcrDetailVo(); final PurchaseOcrDetailVo purchaseOcrDetailVo = new PurchaseOcrDetailVo();
@ -634,7 +638,7 @@ public class AliOcrUtil {
purchaseOcrDetailVo.setSize(s); purchaseOcrDetailVo.setSize(s);
attributeList.add(purchaseOcrDetailVo); attributeList.add(purchaseOcrDetailVo);
} }
}else if(size.contains("-")){ } else if (size.contains("-")) {
final String[] sizeArray = size.split("-"); final String[] sizeArray = size.split("-");
for (String s : sizeArray) { for (String s : sizeArray) {
final PurchaseOcrDetailVo purchaseOcrDetailVo = new PurchaseOcrDetailVo(); final PurchaseOcrDetailVo purchaseOcrDetailVo = new PurchaseOcrDetailVo();
@ -642,7 +646,7 @@ public class AliOcrUtil {
purchaseOcrDetailVo.setSize(s); purchaseOcrDetailVo.setSize(s);
attributeList.add(purchaseOcrDetailVo); attributeList.add(purchaseOcrDetailVo);
} }
}else{ } else {
final PurchaseOcrDetailVo purchaseOcrDetailVo = new PurchaseOcrDetailVo(); final PurchaseOcrDetailVo purchaseOcrDetailVo = new PurchaseOcrDetailVo();
purchaseOcrDetailVo.setColor(attributeListJson.getString("color")); purchaseOcrDetailVo.setColor(attributeListJson.getString("color"));
purchaseOcrDetailVo.setSize(size); purchaseOcrDetailVo.setSize(size);
@ -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