ocr识别修改
This commit is contained in:
@@ -21,6 +21,15 @@ import java.math.BigDecimal;
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class OrderInfoAddDTO implements Serializable {
|
||||
/**
|
||||
* 上菜方式
|
||||
* 待起菜 PENDING_PREP
|
||||
* 待出菜 READY_TO_SERVE
|
||||
* 已出菜 SENT_OUT
|
||||
* 已上菜 DELIVERED
|
||||
* 已超时 EXPIRED
|
||||
*/
|
||||
private String subStatus;
|
||||
//限时折扣部分
|
||||
private LimitRateDTO limitRate;
|
||||
|
||||
|
||||
@@ -8,13 +8,17 @@ import com.alibaba.dashscope.app.ApplicationParam;
|
||||
import com.alibaba.dashscope.app.ApplicationResult;
|
||||
import com.alibaba.dashscope.app.RagOptions;
|
||||
import com.aliyun.bailian20231229.Client;
|
||||
import com.aliyun.bailian20231229.models.AddFileResponse;
|
||||
import com.aliyun.bailian20231229.models.ApplyFileUploadLeaseResponse;
|
||||
import com.aliyun.bailian20231229.models.ApplyFileUploadLeaseResponseBody;
|
||||
import com.aliyun.bailian20231229.models.DescribeFileResponse;
|
||||
import com.czg.exception.CzgException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -53,13 +57,14 @@ public class AliOcrUtil {
|
||||
|
||||
|
||||
|
||||
public static ApplyFileUploadLeaseResponseBody.ApplyFileUploadLeaseResponseBodyData applyFileUpload(InputStream stream, String fileName) {
|
||||
String md5 = DigestUtil.md5Hex(stream);
|
||||
public static ApplyFileUploadLeaseResponseBody.ApplyFileUploadLeaseResponseBodyData applyFileUpload(byte[] bytes, String fileName) {
|
||||
|
||||
String md5 = DigestUtil.md5Hex(bytes);
|
||||
com.aliyun.bailian20231229.Client client = createClient();
|
||||
com.aliyun.bailian20231229.models.ApplyFileUploadLeaseRequest applyFileUploadLeaseRequest = new com.aliyun.bailian20231229.models.ApplyFileUploadLeaseRequest()
|
||||
.setFileName(fileName)
|
||||
.setMd5(md5)
|
||||
.setSizeInBytes("100000")
|
||||
.setSizeInBytes(String.valueOf(bytes.length))
|
||||
.setCategoryType("SESSION_FILE")
|
||||
.setUseInternalEndpoint(false);
|
||||
com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
|
||||
@@ -76,40 +81,94 @@ public class AliOcrUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public static String uploadFile(InputStream stream, String fileName) throws Exception {
|
||||
public static String getSessionId(byte[] bytes, String fileName) {
|
||||
String leaseId = null;
|
||||
try {
|
||||
leaseId = uploadFile(bytes, fileName);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
com.aliyun.bailian20231229.Client client = createClient();
|
||||
com.aliyun.bailian20231229.models.AddFileRequest addFileRequest = new com.aliyun.bailian20231229.models.AddFileRequest()
|
||||
.setLeaseId(leaseId)
|
||||
.setParser("DASHSCOPE_DOCMIND")
|
||||
.setCategoryId("default")
|
||||
.setCategoryType("SESSION_FILE");
|
||||
com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
|
||||
java.util.Map<String, String> headers = new java.util.HashMap<>();
|
||||
try {
|
||||
// 复制代码运行请自行打印 API 的返回值
|
||||
AddFileResponse addFileResponse = client.addFileWithOptions("llm-9zg04s7wlbvi32tq", addFileRequest, headers, runtime);
|
||||
String fileId = addFileResponse.getBody().getData().getFileId();
|
||||
while (!getFileStatus(fileId)) {
|
||||
Thread.sleep(100);
|
||||
}
|
||||
return fileId;
|
||||
} catch (Exception error) {
|
||||
throw new RuntimeException(error);
|
||||
}
|
||||
}
|
||||
|
||||
ApplyFileUploadLeaseResponseBody.ApplyFileUploadLeaseResponseBodyData applyInfo = applyFileUpload(stream, fileName);
|
||||
public static boolean getFileStatus(String fileId) {
|
||||
com.aliyun.bailian20231229.Client client = createClient();
|
||||
com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
|
||||
java.util.Map<String, String> headers = new java.util.HashMap<>();
|
||||
try {
|
||||
// 复制代码运行请自行打印 API 的返回值
|
||||
DescribeFileResponse describeFileResponse = client.describeFileWithOptions("llm-9zg04s7wlbvi32tq", fileId, headers, runtime);
|
||||
|
||||
log.info("file status: {}", describeFileResponse.getBody());
|
||||
return describeFileResponse.getBody().getData() != null && "FILE_IS_READY".equals(describeFileResponse.getBody().getData().getStatus());
|
||||
} catch (Exception error) {
|
||||
throw new RuntimeException(error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static String uploadFile(byte[] bytes, String fileName) throws Exception {
|
||||
|
||||
ApplyFileUploadLeaseResponseBody.ApplyFileUploadLeaseResponseBodyData applyInfo = applyFileUpload(bytes, fileName);
|
||||
|
||||
// 获取预签名要求的所有头
|
||||
Map<String, String> headers = (Map<String, String>) applyInfo.getParam().getHeaders();
|
||||
|
||||
// 补充必须的 Content-Type
|
||||
if (!headers.containsKey("Content-Type")) {
|
||||
headers.put("Content-Type", "application/octet-stream");
|
||||
}
|
||||
|
||||
HttpRequest request = HttpRequest.put(applyInfo.getParam().getUrl());
|
||||
|
||||
// 必须一模一样地设置所有 headers(否则签名失效)
|
||||
// 设置所有 header
|
||||
for (Map.Entry<String, String> entry : headers.entrySet()) {
|
||||
request.header(entry.getKey(), entry.getValue());
|
||||
}
|
||||
|
||||
// 设置文件内容
|
||||
request.body(stream.readAllBytes());
|
||||
request.body(bytes);
|
||||
|
||||
HttpResponse resp = request.execute();
|
||||
log.info(resp.body());
|
||||
|
||||
log.info("upload status: {}", resp.getStatus());
|
||||
if (resp.getStatus() != 200) {
|
||||
throw new CzgException("OSS 上传失败: " + resp.body());
|
||||
}
|
||||
|
||||
return applyInfo.getFileUploadLeaseId();
|
||||
}
|
||||
|
||||
|
||||
public static String appCall(InputStream stream, String fileName) {
|
||||
|
||||
public static String appCall(byte[] bytes, String fileName) {
|
||||
String id = null;
|
||||
try {
|
||||
id = uploadFile(stream, fileName);
|
||||
id = getSessionId(bytes, fileName);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
ApplicationParam param = ApplicationParam.builder()
|
||||
.apiKey("sk-2343af4413834ad1ab43b036e3a903de")
|
||||
.appId("3493340ef5e146c487364395fbca7bf3")
|
||||
.prompt("开始处理")
|
||||
.appId("cd612ac509a4499f8ac68a656532d4ae")
|
||||
.prompt("你是一名票据OCR结构化专家,请从我提供的票据图片中智能提取信息并只输出JSON,不得添加解释、不补充不存在内容、不得返回空字符串、字段缺失填null、字段不可省略、数字一律用字符串,使用以下固定JSON结构:{\"documentType\":\"\",\"orderNumber\":\"\",\"date\":\"\",\"customerName\":\"\",\"operator\":\"\",\"items\":[{\"conName\":\"\",\"spec\":\"\",\"unitName\":\"\",\"inOutNumber\":\"\",\"purchasePrice\":\"\",\"subTotal\":\"\"}],\"totalAmount\":\"\",\"remark\":\"\"}。字段映射规则:documentType对应单据类型/销售单/采购单/出货单;orderNumber对应单号/编号/No;date对应日期/开单日期;customerName对应客户名称/收货单位/供应商;operator对应业务员/经办人/制单人/操作员;items.conName对应品名/名称;items.spec对应规格/型号;items.unitName对应单位;items.inOutNumber对应数量;items.purchasePrice对应单价;items.subTotal对应金额/小计;totalAmount对应总金额/合计金额;remark对应备注。严禁生成图片中不存在的字段内容,看不清或未出现的字段必须为null,不允许推测或补全,不得生成多余字段;items只能根据识别到的行生成,不得虚构。必须能识别旋转、倾斜、模糊、撕裂、光照差异、列顺序混乱、无表格线等情况并尽量恢复信息。最终输出必须是纯JSON,不得包含任何非JSON字符。")
|
||||
.ragOptions(RagOptions.builder()
|
||||
.sessionFileIds(List.of(id))
|
||||
.build())
|
||||
|
||||
@@ -293,6 +293,7 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
|
||||
}
|
||||
}
|
||||
List<OrderDetail> orderDetails = cartService.getCartByTableCode(shopInfo.getId(), param.getTableCode(), param.getPlaceNum());
|
||||
// if (param.)
|
||||
AssertUtil.isListEmpty(orderDetails, "下单失败 购物车为空");
|
||||
processOrderDetails(orderDetails, param.getLimitRate());
|
||||
//生成订单
|
||||
|
||||
@@ -39,6 +39,8 @@ import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
@@ -268,18 +270,25 @@ public class ConsStockFlowServiceImpl extends ServiceImpl<ConsStockFlowMapper, C
|
||||
@Override
|
||||
public Integer ocr(String originalFilename, InputStream inputStream) {
|
||||
Long shopId = StpKit.USER.getShopId();
|
||||
String md5 = DigestUtil.md5Hex(inputStream);
|
||||
byte[] readAllBytes = null;
|
||||
try {
|
||||
readAllBytes = inputStream.readAllBytes();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
String md5 = DigestUtil.md5Hex(readAllBytes);
|
||||
MkOcr ocr = ocrService.getOne(new QueryWrapper().eq(MkOcr::getShopId, shopId).eq(MkOcr::getMd5, md5));
|
||||
if (ocr != null) {
|
||||
return ocr.getId();
|
||||
// return ocr.getId();
|
||||
}
|
||||
MkOcr mkOcr = new MkOcr();
|
||||
mkOcr.setShopId(shopId);
|
||||
mkOcr.setMd5(md5);
|
||||
ocrService.save(mkOcr);
|
||||
byte[] finalReadAllBytes1 = readAllBytes;
|
||||
ThreadUtil.execAsync(() -> {
|
||||
try {
|
||||
String infoStr = AliOcrUtil.appCall(inputStream, originalFilename);
|
||||
String infoStr = AliOcrUtil.appCall(finalReadAllBytes1, originalFilename);
|
||||
SaleOrderDTO saleOrderDTO = JSONObject.parseObject(infoStr, SaleOrderDTO.class);
|
||||
|
||||
ArrayList<ConsInOutStockBodyParam> bodyList = new ArrayList<>();
|
||||
@@ -319,7 +328,7 @@ public class ConsStockFlowServiceImpl extends ServiceImpl<ConsStockFlowMapper, C
|
||||
}catch (Exception e) {
|
||||
mkOcr.setErr(e.getMessage());
|
||||
mkOcr.setStatus("FAILED");
|
||||
log.warn("ocr失败: {}", e.getMessage());
|
||||
log.error("ocr失败:", e);
|
||||
}finally {
|
||||
ocrService.updateById(mkOcr);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user