Merge remote-tracking branch 'origin/test' into test

This commit is contained in:
2025-11-26 10:04:29 +08:00
12 changed files with 234 additions and 41 deletions

View File

@@ -1,6 +1,5 @@
package com.czg.controller.admin; package com.czg.controller.admin;
import com.czg.annotation.SaStaffCheckPermission;
import com.czg.log.annotation.OperationLog; import com.czg.log.annotation.OperationLog;
import com.czg.product.dto.ConsStockFlowDTO; import com.czg.product.dto.ConsStockFlowDTO;
import com.czg.product.param.ConsCheckStockParam; import com.czg.product.param.ConsCheckStockParam;
@@ -41,10 +40,21 @@ public class ConsStockFlowController {
* @throws IOException * @throws IOException
*/ */
@PostMapping("/ocr") @PostMapping("/ocr")
public CzgResult<ConsInOutStockHeadParam> ocr(@RequestParam MultipartFile file) throws IOException { public CzgResult<Integer> ocr(@RequestParam MultipartFile file) throws IOException {
return CzgResult.success(consStockFlowService.ocr(file.getOriginalFilename(), file.getInputStream())); return CzgResult.success(consStockFlowService.ocr(file.getOriginalFilename(), file.getInputStream()));
} }
/**
* ocr识别结果
* @param id ocrId
* @return 识别结果
*/
@GetMapping("/ocrResult")
public CzgResult<ConsInOutStockHeadParam> ocrResult(@RequestParam Long id) {
return CzgResult.success(consStockFlowService.ocrDetail(id));
}
/** /**
* 耗材入库 * 耗材入库
*/ */

View File

@@ -7,6 +7,9 @@ spring:
profiles: profiles:
active: dev active: dev
include: tools include: tools
servlet:
multipart:
max-file-size: 10MB
wx: wx:
ysk: ysk:
appId: wx212769170d2c6b2a appId: wx212769170d2c6b2a

View File

@@ -0,0 +1,43 @@
package com.czg.market.dto;
import java.io.Serializable;
import java.time.LocalDateTime;
import com.alibaba.fastjson2.annotation.JSONField;
import lombok.experimental.Accessors;
import java.io.Serial;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* ocr识别结果 实体类。
*
* @author zs
* @since 2025-11-26
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class MkOcrDTO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
private Integer id;
/**
* 响应内容
*/
private String resp;
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;
@JSONField(format = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime updateTime;
private Integer shopId;
}

View File

@@ -0,0 +1,49 @@
package com.czg.market.entity;
import com.mybatisflex.annotation.Column;
import com.mybatisflex.annotation.Id;
import com.mybatisflex.annotation.KeyType;
import com.mybatisflex.annotation.Table;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.io.Serial;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* ocr识别结果 实体类。
*
* @author zs
* @since 2025-11-26
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Table("mk_ocr")
public class MkOcr implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@Id(keyType = KeyType.Auto)
private Integer id;
/**
* 响应内容
*/
private String resp;
@Column(onInsertValue = "now()")
private LocalDateTime createTime;
@Column(onInsertValue = "now()", onUpdateValue = "now()")
private LocalDateTime updateTime;
private Long shopId;
}

View File

@@ -0,0 +1,14 @@
package com.czg.product.entity;
import com.mybatisflex.core.service.IService;
import com.czg.market.entity.MkOcr;
/**
* ocr识别结果 服务层。
*
* @author zs
* @since 2025-11-26
*/
public interface MkOcrService extends IService<MkOcr> {
}

View File

@@ -78,5 +78,7 @@ public interface ConsStockFlowService extends IService<ConsStockFlow> {
*/ */
void saveFlow(ConsStockFlow entity); void saveFlow(ConsStockFlow entity);
ConsInOutStockHeadParam ocr(String originalFilename, InputStream inputStream); Integer ocr(String originalFilename, InputStream inputStream);
ConsInOutStockHeadParam ocrDetail(Long id);
} }

View File

@@ -29,13 +29,13 @@ public class Main {
// orSqlTest(); // orSqlTest();
String packageName = "system"; // String packageName = "system";
// String packageName = "account"; // String packageName = "account";
// String packageName = "product"; // String packageName = "product";
// String packageName = "market"; String packageName = "market";
// tableName 指定需要生成的表 // tableName 指定需要生成的表
String tableName = "sys_devices"; String tableName = "mk_ocr";
String author = "ww"; String author = "zs";
//是否生成DTO实体 默认生成 //是否生成DTO实体 默认生成
boolean isGenerateDto = true; boolean isGenerateDto = true;

View File

@@ -1729,9 +1729,12 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
if (orderDetail == null) { if (orderDetail == null) {
log.warn("订单详情不存在"); log.warn("订单详情不存在");
} }
if (orderDetail.getSubStatus() == null) {
return;
}
if (!orderDetail.getSubStatus().equals(TableValueConstant.OrderDetail.SubStatus.READY_TO_SERVE.getCode()) if (!TableValueConstant.OrderDetail.SubStatus.READY_TO_SERVE.getCode().equals(orderDetail.getSubStatus())
&& !orderDetail.getSubStatus().equals(TableValueConstant.OrderDetail.SubStatus.SENT_OUT.getCode())) { && !TableValueConstant.OrderDetail.SubStatus.SENT_OUT.getCode().equals(orderDetail.getSubStatus())) {
log.warn("订单详情状态不正确"); log.warn("订单详情状态不正确");
return; return;
} }

View File

@@ -0,0 +1,14 @@
package com.czg.service.product.mapper;
import com.mybatisflex.core.BaseMapper;
import com.czg.market.entity.MkOcr;
/**
* ocr识别结果 映射层。
*
* @author zs
* @since 2025-11-26
*/
public interface MkOcrMapper extends BaseMapper<MkOcr> {
}

View File

@@ -9,6 +9,8 @@ import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.czg.exception.CzgException; import com.czg.exception.CzgException;
import com.czg.market.entity.MkOcr;
import com.czg.product.entity.MkOcrService;
import com.czg.product.dto.ConsStockFlowDTO; import com.czg.product.dto.ConsStockFlowDTO;
import com.czg.product.dto.SaleOrderDTO; import com.czg.product.dto.SaleOrderDTO;
import com.czg.product.entity.ConsInfo; import com.czg.product.entity.ConsInfo;
@@ -57,6 +59,8 @@ public class ConsStockFlowServiceImpl extends ServiceImpl<ConsStockFlowMapper, C
private final ProductMapper productMapper; private final ProductMapper productMapper;
@Resource @Resource
private WxAccountUtil wxAccountUtil; private WxAccountUtil wxAccountUtil;
@Resource
private MkOcrService ocrService;
private QueryWrapper buildQueryWrapper(ConsStockFlowDTO param) { private QueryWrapper buildQueryWrapper(ConsStockFlowDTO param) {
QueryWrapper queryWrapper = PageUtil.buildSortQueryWrapper(); QueryWrapper queryWrapper = PageUtil.buildSortQueryWrapper();
@@ -261,40 +265,66 @@ public class ConsStockFlowServiceImpl extends ServiceImpl<ConsStockFlowMapper, C
} }
@Override @Override
public ConsInOutStockHeadParam ocr(String originalFilename, InputStream inputStream) { public Integer ocr(String originalFilename, InputStream inputStream) {
String infoStr = AliOcrUtil.appCall(inputStream, originalFilename); Long shopId = StpKit.USER.getShopId();
SaleOrderDTO saleOrderDTO = JSONObject.parseObject(infoStr, SaleOrderDTO.class); MkOcr mkOcr = new MkOcr();
mkOcr.setShopId(shopId);
ocrService.save(mkOcr);
ThreadUtil.execAsync(() -> {
try {
ArrayList<ConsInOutStockBodyParam> bodyList = new ArrayList<>(); String infoStr = AliOcrUtil.appCall(inputStream, originalFilename);
Set<String> nameList = saleOrderDTO.getItems().stream().map(SaleOrderDTO.Item::getConName).collect(Collectors.toSet()); SaleOrderDTO saleOrderDTO = JSONObject.parseObject(infoStr, SaleOrderDTO.class);
Map<String, ConsInfo> consInfoMap = new HashMap<>();
if (!nameList.isEmpty()) { ArrayList<ConsInOutStockBodyParam> bodyList = new ArrayList<>();
consInfoMap = consInfoMapper.selectListByQuery(new QueryWrapper().in(ConsInfo::getConName, nameList)) Set<String> nameList = saleOrderDTO.getItems().stream().map(SaleOrderDTO.Item::getConName).collect(Collectors.toSet());
.stream().collect(Collectors.toMap(ConsInfo::getConName, consInfo -> consInfo)); Map<String, ConsInfo> consInfoMap = new HashMap<>();
} if (!nameList.isEmpty()) {
ArrayList<SaleOrderDTO.Item> unInCons = new ArrayList<>(); consInfoMap = consInfoMapper.selectListByQuery(new QueryWrapper().in(ConsInfo::getConName, nameList).eq(ConsInfo::getShopId, shopId))
for (SaleOrderDTO.Item item : saleOrderDTO.getItems()) { .stream().collect(Collectors.toMap(ConsInfo::getConName, consInfo -> consInfo));
ConsInfo consInfo = consInfoMap.get(item.getConName()); }
if (consInfo == null) { ArrayList<SaleOrderDTO.Item> unInCons = new ArrayList<>();
unInCons.add(item); for (SaleOrderDTO.Item item : saleOrderDTO.getItems()) {
continue; ConsInfo consInfo = consInfoMap.get(item.getConName());
if (consInfo == null) {
unInCons.add(item);
continue;
}
bodyList.add(new ConsInOutStockBodyParam()
.setConId(consInfo.getId().toString())
.setConName(consInfo.getConName())
.setPurchasePrice(new BigDecimal(item.getPurchasePrice()))
.setUnitName(item.getUnitName())
.setSubTotal(new BigDecimal(item.getSubTotal()))
.setInOutNumber(new BigDecimal(item.getInOutNumber())));
}
ConsInOutStockHeadParam headParam = new ConsInOutStockHeadParam();
headParam.setBatchNo(saleOrderDTO.getOrderNumber())
.setInOutDate(LocalDate.parse(saleOrderDTO.getDate()))
.setAmountPayable(new BigDecimal(saleOrderDTO.getTotalAmount()))
.setBodyList(bodyList)
.setUnInCons(unInCons)
.setOcrSaleOrder(saleOrderDTO);
mkOcr.setResp(JSON.toJSONString(headParam));
ocrService.updateById(mkOcr);
}catch (Exception e) {
log.warn("ocr失败: {}", e.getMessage());
} }
bodyList.add(new ConsInOutStockBodyParam()
.setConId(consInfo.getId().toString())
.setConName(consInfo.getConName())
.setPurchasePrice(new BigDecimal(item.getPurchasePrice()))
.setUnitName(item.getUnitName())
.setSubTotal(new BigDecimal(item.getSubTotal()))
.setInOutNumber(new BigDecimal(item.getInOutNumber())));
}
ConsInOutStockHeadParam headParam = new ConsInOutStockHeadParam(); });
headParam.setBatchNo(saleOrderDTO.getOrderNumber())
.setInOutDate(LocalDate.parse(saleOrderDTO.getDate())) return mkOcr.getId();
.setAmountPayable(new BigDecimal(saleOrderDTO.getTotalAmount())) }
.setBodyList(bodyList)
.setUnInCons(unInCons) @Override
.setOcrSaleOrder(saleOrderDTO); public ConsInOutStockHeadParam ocrDetail(Long id) {
return headParam; MkOcr mkOcr = ocrService.getOne(new QueryWrapper().eq(MkOcr::getShopId, StpKit.USER.getShopId()).eq(MkOcr::getId, id));
if (StrUtil.isNotBlank(mkOcr.getResp())) {
return JSONObject.parseObject(mkOcr.getResp(), ConsInOutStockHeadParam.class);
}
return null;
} }
} }

View File

@@ -0,0 +1,18 @@
package com.czg.service.product.service.impl;
import com.czg.service.product.mapper.MkOcrMapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.czg.market.entity.MkOcr;
import com.czg.product.entity.MkOcrService;
import org.springframework.stereotype.Service;
/**
* ocr识别结果 服务层实现。
*
* @author zs
* @since 2025-11-26
*/
@Service
public class MkOcrServiceImpl extends ServiceImpl<MkOcrMapper, MkOcr> implements MkOcrService{
}

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.czg.service.product.mapper.MkOcrMapper">
</mapper>