From 13355ac73b8b177f426d842ee79bdc67a2a7d6eb Mon Sep 17 00:00:00 2001 From: "zhenghaiyang@ele-cloud.com" Date: Fri, 17 Mar 2023 20:08:18 +0800 Subject: [PATCH 1/7] =?UTF-8?q?feature=201.=E6=8F=90=E4=BA=A4OCR=E8=AF=86?= =?UTF-8?q?=E5=88=AB=E7=9A=84=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dxhy-common/pom.xml | 4 + .../java/com/dxhy/common/util/FileUtil.java | 25 ++ .../impl/OpenServicePlatformServiceImpl.java | 312 ++++++++++++++++-- .../model/ocr/OcrDataListEntity.java | 36 ++ .../model/ocr/OcrDataTypeEnum.java | 197 +++++++++++ .../model/ocr/OcrItemListEntity.java | 13 + .../model/ocr/OcrProductListEntity.java | 12 + .../openservice/model/ocr/OcrResponseVo.java | 15 + .../model/ocr/OcrResultEntity.java | 14 + 9 files changed, 594 insertions(+), 34 deletions(-) create mode 100644 dxhy-core/src/main/java/com/dxhy/core/service/openservice/model/ocr/OcrDataListEntity.java create mode 100644 dxhy-core/src/main/java/com/dxhy/core/service/openservice/model/ocr/OcrDataTypeEnum.java create mode 100644 dxhy-core/src/main/java/com/dxhy/core/service/openservice/model/ocr/OcrItemListEntity.java create mode 100644 dxhy-core/src/main/java/com/dxhy/core/service/openservice/model/ocr/OcrProductListEntity.java create mode 100644 dxhy-core/src/main/java/com/dxhy/core/service/openservice/model/ocr/OcrResponseVo.java create mode 100644 dxhy-core/src/main/java/com/dxhy/core/service/openservice/model/ocr/OcrResultEntity.java diff --git a/dxhy-common/pom.xml b/dxhy-common/pom.xml index 8dc0d9b9..fdd134f4 100644 --- a/dxhy-common/pom.xml +++ b/dxhy-common/pom.xml @@ -169,6 +169,10 @@ redis.clients jedis + + org.apache.httpcomponents + httpmime + diff --git a/dxhy-common/src/main/java/com/dxhy/common/util/FileUtil.java b/dxhy-common/src/main/java/com/dxhy/common/util/FileUtil.java index 40e14f8f..aad66723 100644 --- a/dxhy-common/src/main/java/com/dxhy/common/util/FileUtil.java +++ b/dxhy-common/src/main/java/com/dxhy/common/util/FileUtil.java @@ -1,8 +1,16 @@ package com.dxhy.common.util; import java.io.*; +import java.nio.charset.Charset; import cn.hutool.core.codec.Base64; +import org.apache.commons.io.IOUtils; +import org.apache.http.HttpEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.mime.MultipartEntityBuilder; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; /** * @author jiaohongyang @@ -163,4 +171,21 @@ public class FileUtil { return base64; } + //新增文件上传接口 + public static String uploadFile(String url, String fileStream) { + HttpPost httpPost = new HttpPost(url); + MultipartEntityBuilder builder = MultipartEntityBuilder.create(); + builder.addBinaryBody("file",fileStream.getBytes(Charset.forName("UTF-8"))); + HttpEntity multipart = builder.build(); + httpPost.setEntity(multipart); + String result = ""; + try { + CloseableHttpResponse response = HttpClients.createDefault().execute(httpPost); + InputStream content = response.getEntity().getContent(); + result = IOUtils.toString(content, "utf-8"); + } catch (IOException e) { + throw new RuntimeException(e); + } + return result; + } } diff --git a/dxhy-core/src/main/java/com/dxhy/core/service/openservice/impl/OpenServicePlatformServiceImpl.java b/dxhy-core/src/main/java/com/dxhy/core/service/openservice/impl/OpenServicePlatformServiceImpl.java index 40051567..e64e1122 100644 --- a/dxhy-core/src/main/java/com/dxhy/core/service/openservice/impl/OpenServicePlatformServiceImpl.java +++ b/dxhy-core/src/main/java/com/dxhy/core/service/openservice/impl/OpenServicePlatformServiceImpl.java @@ -1,12 +1,16 @@ package com.dxhy.core.service.openservice.impl; -import java.util.Date; -import java.util.List; -import java.util.Optional; -import java.util.UUID; +import java.io.*; +import java.util.*; +import java.util.stream.Collectors; import javax.annotation.Resource; +import cn.hutool.core.codec.Base64Decoder; +import com.dxhy.common.util.FileUtil; +import com.dxhy.core.service.openservice.model.ocr.*; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; @@ -57,6 +61,8 @@ public class OpenServicePlatformServiceImpl implements IOpenServicePlatformServi private String ocrTaxno; @Value("${openService.ocrUrl:}") private String ocrUrl; + @Value("${sn.ocrUrl:}") + private String snOcrUrl; @Resource private MakeAppSecService makeAppSecService; @@ -154,38 +160,276 @@ public class OpenServicePlatformServiceImpl implements IOpenServicePlatformServi @Override public List ocrInvoice(String picture, String userName, String password, String taxno) { + return OcrToSn(picture); +// String sendDate = DateUtil.format(new Date(), DatePattern.PURE_DATETIME_PATTERN); +// String signStr = "username=%s&sendDate=%s&version=%s"; +// String version = "1.0"; +// if (StringUtils.isBlank(userName) || StringUtils.isBlank(password) || StringUtils.isBlank(taxno)) { +// userName = ocrUserName; +// password = ocrPassword; +// taxno = ocrTaxno; +// } +// signStr = String.format(signStr, userName, sendDate, version); +// JSONObject dataJson = new JSONObject(); +// dataJson.put("taxno", taxno); +// dataJson.put("picture", picture); +// JSONObject json = new JSONObject(); +// json.put("username", userName); +// json.put("password", password); +// json.put("sendDate", sendDate); +// json.put("signature", makeAppSecService.getSign(signStr, password)); +// json.put("version", version); +// log.info("请求报文,去除picture:{} , picture是否有值:{}", json.toJSONString(), StringUtils.isNotBlank(picture)); +// json.put("data", Base64.encode(dataJson.toString())); +// +// String post = HttpUtil.post(ocrUrl, json.toString(), 60000); +// log.info("ocr识别结果:{}", post); +// JSONObject jsonObject = JSONObject.parseObject(post, JSONObject.class); +// String returnCode = jsonObject.getString("returnCode"); +// +// if (!"0000".equals(returnCode)) { +// return null; +// } +// +// String decodeStr = Base64.decodeStr(jsonObject.getString("data")); +// return JSONObject.parseArray(decodeStr, OpenServiceOcr.class); + } - String sendDate = DateUtil.format(new Date(), DatePattern.PURE_DATETIME_PATTERN); - String signStr = "username=%s&sendDate=%s&version=%s"; - String version = "1.0"; - if (StringUtils.isBlank(userName) || StringUtils.isBlank(password) || StringUtils.isBlank(taxno)) { - userName = ocrUserName; - password = ocrPassword; - taxno = ocrTaxno; - } - signStr = String.format(signStr, userName, sendDate, version); - JSONObject dataJson = new JSONObject(); - dataJson.put("taxno", taxno); - dataJson.put("picture", picture); - JSONObject json = new JSONObject(); - json.put("username", userName); - json.put("password", password); - json.put("sendDate", sendDate); - json.put("signature", makeAppSecService.getSign(signStr, password)); - json.put("version", version); - log.info("请求报文,去除picture:{} , picture是否有值:{}", json.toJSONString(), StringUtils.isNotBlank(picture)); - json.put("data", Base64.encode(dataJson.toString())); - - String post = HttpUtil.post(ocrUrl, json.toString(), 60000); - log.info("ocr识别结果:{}", post); - JSONObject jsonObject = JSONObject.parseObject(post, JSONObject.class); - String returnCode = jsonObject.getString("returnCode"); - - if (!"0000".equals(returnCode)) { - return null; + /** + * Ocr识别使用山能 + * @param picture 文件流 + * @return + */ + public List OcrToSn(String picture){ + //判断是否为图片流文件, 兼容公司平台进行base64解密 + String str = Base64Decoder.decodeStr(picture); + String requestUrl = snOcrUrl; + String result = FileUtil.uploadFile(requestUrl, str); + if(StringUtils.isBlank(result)){ + log.info("调用山能ocr识别失败"); + }else { + OcrResponseVo ocrResponseVo = JSONObject.parseObject(result, OcrResponseVo.class); + if(ocrResponseVo != null && ocrResponseVo.getCode() == 200){ + List ocrDataListEntities = ocrResponseVo.getResult().getObjectList(); + return dxOcrConvertSnOcr(ocrDataListEntities); + } } + return null; + } + + //实现实体类转换 + public List dxOcrConvertSnOcr(List ocrDataListEntities){ + List openServices = Lists.newArrayList(); + for (OcrDataListEntity ocrDataListEntity : ocrDataListEntities) { + OpenServiceOcr serviceOcr = new OpenServiceOcr(); + List> productList = ocrDataListEntity.getProductList(); + + List itemList = ocrDataListEntity.getItemList(); + + Map itemData = itemList.stream().collect(Collectors.toMap(OcrItemListEntity::getKey, OcrItemListEntity::getValue)); + OpenServiceOcr openServiceOcr = new OpenServiceOcr(); + + String type = ocrDataListEntity.getType(); + //type 为 vat_special_invoice(增值税专用发票)、vat_electronic_invoice(增 + //值税电子普通发票)、vat_common_invoice(增值税普通发票)、 + //vat_electronic_toll_invoice(增值税电子普通发票(通行费)) + //type 为 motor_vehicle_sale_invoice(机动车销售统一发票) + //type 为 used_car_purchase_invoice(二手车销售统一发票) + //type 为 vat_roll_invoice(增值税普通发票(卷票)) + //type 为 vehicle_toll(过路过桥费发票、汽车通行费) + //type 为 quota_invoice(通用定额发票) + //type 为 taxi_ticket(出租车发票) + //type 为 air_transport(行程单) + //type 为 train_ticket(火车票) + //type 为 general_machine_invoice(通用机打发票)、 highway_passenger_invoice(公路客运发票)、shipping_invoice(船运客票)、passenger_transport_invoice(旅客运输普票) + //type 为 parking_invoice(停车费发票) + + openServiceOcr.setFPLXDM(itemData.get(OcrDataTypeEnum.VAT_INVOICE_TYPE.getKey())); +// openServiceOcr.setXZJD(itemData.get(OcrDataTypeEnum.VAT_INVOICE_TYPE.getKey())); + + OpenServiceOcr.InvoiceOcrData invoiceOcrData = new OpenServiceOcr.InvoiceOcrData(); + invoiceOcrData.setSFCY("0"); //是否查验 + //判断发票类型 + if("vat_special_invoice".equals(type) || "vat_electronic_invoice".equals(type) || "vat_common_invoice".equals(type) || "vat_electronic_toll_invoice".equals(type)){ + invoiceOcrData.setJYM(itemData.get(OcrDataTypeEnum.VAT_INVOICE_CORRECT_CODE.getKey())); + invoiceOcrData.setFPDM(itemData.get(OcrDataTypeEnum.VAT_INVOICE_DAIMA.getKey())); + invoiceOcrData.setFPHM(itemData.get(OcrDataTypeEnum.VAT_INVOICE_HAOMA.getKey())); + + invoiceOcrData.setKPRQ(itemData.get(OcrDataTypeEnum.VAT_INVOICE_ISSUE_DATE.getKey())); + invoiceOcrData.setGMFSBH(itemData.get(OcrDataTypeEnum.VAT_INVOICE_RATE_PAYER_ID.getKey())); + - String decodeStr = Base64.decodeStr(jsonObject.getString("data")); - return JSONObject.parseArray(decodeStr, OpenServiceOcr.class); + invoiceOcrData.setJDHM(itemData.get(OcrDataTypeEnum.VAT_INVOICE_JIDA_HAOMA.getKey())); + invoiceOcrData.setXHFMC(itemData.get(OcrDataTypeEnum.VAT_INVOICE_SELLER_NAME.getKey())); + invoiceOcrData.setXHFSBH(itemData.get(OcrDataTypeEnum.VAT_INVOICE_SELLER_ID.getKey())); + invoiceOcrData.setXHFDZDH(itemData.get(OcrDataTypeEnum.VAT_INVOICE_SELLER_ADDR_TELL.getKey())); + invoiceOcrData.setXHFYHZH(itemData.get(OcrDataTypeEnum.VAT_INVOICE_SELLER_BANK_ACCOUNT.getKey())); + invoiceOcrData.setGMFMC(itemData.get(OcrDataTypeEnum.VAT_INVOICE_PAYER_NAME.getKey())); + invoiceOcrData.setGMFDZDH(itemData.get(OcrDataTypeEnum.VAT_INVOICE_PAYER_ADDR_TELL.getKey())); + invoiceOcrData.setGMFYHZH(itemData.get(OcrDataTypeEnum.VAT_INVOICE_PAYER_BANK_ACCOUNT.getKey())); + + invoiceOcrData.setHJJE(itemData.get(OcrDataTypeEnum.VAT_INVOICE_PRICE_LIST.getKey())); + + + //是否代开 vat_invoice_zhuan_yong_flag TODO + invoiceOcrData.setSFDK(itemData.get(OcrDataTypeEnum.VAT_INVOICE_DAI_KAI_FLAG.getKey())); + invoiceOcrData.setHJSE(itemData.get(OcrDataTypeEnum.VAT_INVOICE_TAX_TOTAL.getKey())); + + invoiceOcrData.setJSHJ(itemData.get(OcrDataTypeEnum.VAT_INVOICE_TOTAL_COVER_TAX_DIGITS.getKey())); + invoiceOcrData.setFPLC(itemData.get(OcrDataTypeEnum.VAT_INVOICE_PAGE_NUMBER.getKey())); + openServiceOcr.setFPLXDM(itemData.get(OcrDataTypeEnum.VAT_INVOICE_TYPE.getKey())); + invoiceOcrData.setBZ(itemData.get(OcrDataTypeEnum.VAT_INVOICE_TOTAL_NOTE.getKey())); + invoiceOcrData.setFWM(itemData.get(OcrDataTypeEnum.VAT_INVOICE_CIPHER_FIELD.getKey())); + invoiceOcrData.setSKR(itemData.get(OcrDataTypeEnum.VAT_INVOICE_PAYEE.getKey())); + invoiceOcrData.setFHR(itemData.get(OcrDataTypeEnum.VAT_INVOICE_REVIEW.getKey())); + invoiceOcrData.setKPR(itemData.get(OcrDataTypeEnum.VAT_INVOICE_DRAWER.getKey())); + invoiceOcrData.setSFYGSYZ("False".equals(itemData.get(OcrDataTypeEnum.EXIST_STAMPLE.getKey()))?"0":"1"); + + List invoiceOcrDetailList = Lists.newArrayList(); + for (List productListEntities : productList) { + OpenServiceOcr.InvoiceOcrDetail invoiceOcrDetail = new OpenServiceOcr.InvoiceOcrDetail(); +// invoiceOcrDetail.setMXXH(itemData.get(OcrDataTypeEnum.VAT_INVOICE_TYPE.getKey())); + invoiceOcrDetail.setHWMC(itemData.get(OcrDataTypeEnum.VAT_INVOICE_GOODS.getKey())); + invoiceOcrDetail.setGGXH(itemData.get(OcrDataTypeEnum.VAT_INVOICE_PLATE_SPECIFIC.getKey())); + invoiceOcrDetail.setDW(itemData.get(OcrDataTypeEnum.VAT_INVOICE_ELECTRANS_UNIT.getKey())); + invoiceOcrDetail.setSPSL(itemData.get(OcrDataTypeEnum.VAT_INVOICE_ELECTRANS_QUANTITY.getKey())); + invoiceOcrDetail.setDJ(itemData.get(OcrDataTypeEnum.VAT_INVOICE_ELECTRANS_UNIT_PRICE.getKey())); + invoiceOcrDetail.setJE(itemData.get(OcrDataTypeEnum.VAT_INVOICE_PRICE.getKey())); + invoiceOcrDetail.setSL(itemData.get(OcrDataTypeEnum.VAT_INVOICE_TAX_RATE.getKey())); + invoiceOcrDetail.setSE(itemData.get(OcrDataTypeEnum.VAT_INVOICE_TAX.getKey())); + invoiceOcrDetailList.add(invoiceOcrDetail); + invoiceOcrData.setFPMX(invoiceOcrDetailList); + } + } else if ("vat_roll_invoice".equals(type)) { + invoiceOcrData.setKPRQ(itemData.get(OcrDataTypeEnum.DATE_OF_INVOICE.getKey())); + invoiceOcrData.setFPBT(itemData.get(OcrDataTypeEnum.INVOICE_HEAD.getKey())); + invoiceOcrData.setJYM(itemData.get(OcrDataTypeEnum.CHECK_NUMBER.getKey())); + invoiceOcrData.setFPDM(itemData.get(OcrDataTypeEnum.INVOICE_NUMBER.getKey())); + invoiceOcrData.setFPHM(itemData.get(OcrDataTypeEnum.INVOICE_NUMBER.getKey())); + invoiceOcrData.setJQBM(itemData.get(OcrDataTypeEnum.MACHINE_CODE.getKey())); + invoiceOcrData.setGMFSBH(itemData.get(OcrDataTypeEnum.BUY_TAX_NUMBER.getKey())); + invoiceOcrData.setJSHJ(itemData.get(OcrDataTypeEnum.TOTAL_MONEY.getKey())); + invoiceOcrData.setXHFMC(itemData.get(OcrDataTypeEnum.SOLD_NAME.getKey())); + invoiceOcrData.setXHFSBH(itemData.get(OcrDataTypeEnum.SOLD_TAX_NUMBER.getKey())); + invoiceOcrData.setGMFMC(itemData.get(OcrDataTypeEnum.BUY_NAME.getKey())); + invoiceOcrData.setSKR(itemData.get(OcrDataTypeEnum.CASHIER_NAME.getKey())); + //是否代开 vat_invoice_zhuan_yong_flag TODO + invoiceOcrData.setSFYGSYZ("False".equals(itemData.get(OcrDataTypeEnum.EXIST_STAMPLE.getKey()))?"0":"1"); + + List invoiceOcrDetailList = Lists.newArrayList(); + for (List productListEntities : productList) { + OpenServiceOcr.InvoiceOcrDetail invoiceOcrDetail = new OpenServiceOcr.InvoiceOcrDetail(); +// invoiceOcrDetail.setMXXH(itemData.get(OcrDataTypeEnum.VAT_INVOICE_TYPE.getKey())); + invoiceOcrDetail.setHWMC(itemData.get(OcrDataTypeEnum.VAT_INVOICE_GOODS.getKey())); + invoiceOcrDetail.setGGXH(itemData.get(OcrDataTypeEnum.VAT_INVOICE_PLATE_SPECIFIC.getKey())); + invoiceOcrDetail.setDW(itemData.get(OcrDataTypeEnum.VAT_INVOICE_ELECTRANS_UNIT.getKey())); + invoiceOcrDetail.setSPSL(itemData.get(OcrDataTypeEnum.VAT_INVOICE_ELECTRANS_QUANTITY.getKey())); + invoiceOcrDetail.setDJ(itemData.get(OcrDataTypeEnum.VAT_INVOICE_ELECTRANS_UNIT_PRICE.getKey())); + invoiceOcrDetail.setJE(itemData.get(OcrDataTypeEnum.VAT_INVOICE_PRICE.getKey())); + invoiceOcrDetail.setSL(itemData.get(OcrDataTypeEnum.VAT_INVOICE_TAX_RATE.getKey())); + invoiceOcrDetail.setSE(itemData.get(OcrDataTypeEnum.VAT_INVOICE_TAX.getKey())); + invoiceOcrDetailList.add(invoiceOcrDetail); + invoiceOcrData.setFPMX(invoiceOcrDetailList); + } + } else if ("motor_vehicle_sale_invoice".equals(type)) { + // -------------机动车销售统一发票特殊字段-------------- + invoiceOcrData.setGMFMC(itemData.get(OcrDataTypeEnum.VEHICLE_INVOICE_BUYER.getKey())); + invoiceOcrData.setGMFSBH(itemData.get(OcrDataTypeEnum.VEHICLE_INVOICE_BUYER_ID.getKey())); + invoiceOcrData.setCPXH(itemData.get(OcrDataTypeEnum.VEHICLE_INVOICE_CAR_MODEL.getKey())); + invoiceOcrData.setHGZH(itemData.get(OcrDataTypeEnum.VEHICLE_INVOICE_CERT_ID.getKey())); + invoiceOcrData.setFDJHM(itemData.get(OcrDataTypeEnum.VEHICLE_INVOICE_ENGINE_ID.getKey())); + invoiceOcrData.setCLSBH(itemData.get(OcrDataTypeEnum.VEHICLE_INVOICE_CAR_VIN.getKey())); + invoiceOcrData.setHJJE(itemData.get(OcrDataTypeEnum.VEHICLE_INVOICE_PRICE_WITHOUT_TAX.getKey())); + invoiceOcrData.setZGSWJG(itemData.get(OcrDataTypeEnum.VEHICLE_INVOICE_TAX_AUTHORITH.getKey())); + invoiceOcrData.setZGSWJGDM(itemData.get(OcrDataTypeEnum.VEHICLE_INVOICE_TAX_AUTHORITH_ID.getKey())); + + + invoiceOcrData.setJSHJ(itemData.get(OcrDataTypeEnum.VEHICLE_INVOICE_TOTAL_PRICE_DIGITS.getKey())); + invoiceOcrData.setKPRQ(itemData.get(OcrDataTypeEnum.VEHICLE_INVOICE_ISSUE_DATE.getKey())); + invoiceOcrData.setFPDM(itemData.get(OcrDataTypeEnum.VEHICLE_INVOICE_DAIMA.getKey())); + invoiceOcrData.setFPHM(itemData.get(OcrDataTypeEnum.VEHICLE_INVOICE_HAOMA.getKey())); + } else if ("used_car_purchase_invoice".equals(type)) { + // -------------二手车销售统一发票特殊字段-------------- + invoiceOcrData.setGMFMC(itemData.get(OcrDataTypeEnum.VEHICLE_INVOICE_BUYER.getKey())); + invoiceOcrData.setGMFSBH(itemData.get(OcrDataTypeEnum.VEHICLE_INVOICE_BUYER_ID.getKey())); + invoiceOcrData.setXHFMC(itemData.get(OcrDataTypeEnum.VEHICLE_INVOICE_SELLER.getKey())); + invoiceOcrData.setXHFSBH(itemData.get(OcrDataTypeEnum.VEHICLE_INVOICE_SELLER_ID.getKey())); + invoiceOcrData.setESCSC(itemData.get(OcrDataTypeEnum.VEHICLE_INVOICE_MARKET.getKey())); + invoiceOcrData.setCPZH(itemData.get(OcrDataTypeEnum.VEHICLE_INVOICE_PLATE_NUM.getKey())); + invoiceOcrData.setDJZH(itemData.get(OcrDataTypeEnum.VEHICLE_INVOICE_CAR_MODEL.getKey())); + invoiceOcrData.setCLSBH(itemData.get(OcrDataTypeEnum.VEHICLE_INVOICE_VIN.getKey())); + invoiceOcrData.setCPXH(itemData.get(OcrDataTypeEnum.VEHICLE_INVOICE_CAR_MODEL.getKey())); + invoiceOcrData.setESCNSRSBH(itemData.get(OcrDataTypeEnum.VEHICLE_INVOICE_MARKET_TAX_ID.getKey())); + invoiceOcrData.setESCNSRSBH(itemData.get(OcrDataTypeEnum.VEHICLE_INVOICE_MARKET_TAX_ID.getKey())); + invoiceOcrData.setJSHJ(itemData.get(OcrDataTypeEnum.VEHICLE_INVOICE_TOTAL_PRICE_DIGITS.getKey())); + invoiceOcrData.setKPRQ(itemData.get(OcrDataTypeEnum.VEHICLE_INVOICE_ISSUE_DATE.getKey())); + invoiceOcrData.setFPDM(itemData.get(OcrDataTypeEnum.VEHICLE_INVOICE_DAIMA.getKey())); + invoiceOcrData.setFPHM(itemData.get(OcrDataTypeEnum.VEHICLE_INVOICE_HAOMA.getKey())); + } else if("vehicle_toll".equals(type)){ + // -------------过路费特殊字段-------------- + invoiceOcrData.setJSHJ(itemData.get(OcrDataTypeEnum.MONEY.getKey())); + invoiceOcrData.setKPRQ(itemData.get(OcrDataTypeEnum.DATE.getKey())); + invoiceOcrData.setSJ(itemData.get(OcrDataTypeEnum.TIME.getKey())); + invoiceOcrData.setFPDM(itemData.get(OcrDataTypeEnum.TOLL_CODE.getKey())); + invoiceOcrData.setFPHM(itemData.get(OcrDataTypeEnum.TOLL_NUMBER.getKey())); + + }else if ("quota_invoice".equals(type)) { + invoiceOcrData.setJSHJ(itemData.get(OcrDataTypeEnum.MONEY_SMALL.getKey())); + invoiceOcrData.setFPDM(itemData.get(OcrDataTypeEnum.QUOTA_INVOICE_CODE.getKey())); + invoiceOcrData.setFPHM(itemData.get(OcrDataTypeEnum.QUOTA_INVOICE_NUMBER.getKey())); + + } else if ("taxi_ticket".equals(type)) { + // -------------出租车发票特殊字段-------------- + invoiceOcrData.setJSHJ(itemData.get(OcrDataTypeEnum.SUM.getKey())); + invoiceOcrData.setFPDM(itemData.get(OcrDataTypeEnum.INVOICE_CODE.getKey())); + invoiceOcrData.setFPHM(itemData.get(OcrDataTypeEnum.INVOICE_NO.getKey())); + invoiceOcrData.setKPRQ(itemData.get(OcrDataTypeEnum.DATE.getKey())); + invoiceOcrData.setSCSJ(itemData.get(OcrDataTypeEnum.BOARDING_TIME.getKey())); + invoiceOcrData.setXCSJ(itemData.get(OcrDataTypeEnum.LANDING_TIME.getKey())); + invoiceOcrData.setLC(itemData.get(OcrDataTypeEnum.MILEAGE.getKey())); + invoiceOcrData.setSZD(itemData.get(OcrDataTypeEnum.LOCATION.getKey())); + invoiceOcrData.setCPZH(itemData.get(OcrDataTypeEnum.TAXI_NO.getKey())); + } else if("air_transport".equals(type)){ + invoiceOcrData.setXM(itemData.get(OcrDataTypeEnum.PASSENGER_NAME.getKey())); + invoiceOcrData.setSFZH(itemData.get(OcrDataTypeEnum.ID_NO.getKey())); + invoiceOcrData.setPZHM(itemData.get(OcrDataTypeEnum.E_TICKET_NO.getKey())); + invoiceOcrData.setTKRQ(itemData.get(OcrDataTypeEnum.ISSUED_DATE.getKey())); + invoiceOcrData.setTKDW(itemData.get(OcrDataTypeEnum.ISSUED_BY.getKey())); + invoiceOcrData.setPJ(itemData.get(OcrDataTypeEnum.FARE.getKey())); + invoiceOcrData.setMHFZJJ(itemData.get(OcrDataTypeEnum.CIVIL_AVIATION_FUND.getKey())); + invoiceOcrData.setRYFJF(itemData.get(OcrDataTypeEnum.FUEL_SURCHARGE.getKey())); + invoiceOcrData.setQTSF(itemData.get(OcrDataTypeEnum.OTHER_TAXES.getKey())); + invoiceOcrData.setZE(itemData.get(OcrDataTypeEnum.TOTAL.getKey())); + invoiceOcrData.setBXF(itemData.get(OcrDataTypeEnum.INSURANCE.getKey())); + } else if("train_ticket".equals(type)){ + // -------------火车票特殊字段-------------- +// invoiceOcrData.setPZHM(itemData.get(OcrDataTypeEnum.VAT_INVOICE_TYPE.getKey())); + invoiceOcrData.setKPRQ(itemData.get(OcrDataTypeEnum.DEPARTURE_DATE.getKey())); + invoiceOcrData.setSJ(itemData.get(OcrDataTypeEnum.DEPARTURE_DATE.getKey())); +// invoiceOcrData.setXM(itemData.get(OcrDataTypeEnum.VAT_INVOICE_TYPE.getKey())); + invoiceOcrData.setCFZD(itemData.get(OcrDataTypeEnum.DEPARTURE_STATION.getKey())); + invoiceOcrData.setDDZD(itemData.get(OcrDataTypeEnum.ARRIVAL_STATION.getKey())); + invoiceOcrData.setCC(itemData.get(OcrDataTypeEnum.TRAIN_NUMBER.getKey())); + invoiceOcrData.setZWDJ(itemData.get(OcrDataTypeEnum.CLASS.getKey())); + invoiceOcrData.setXLH(itemData.get(OcrDataTypeEnum.SEAT_NUMBER.getKey())); + invoiceOcrData.setSFZH(itemData.get(OcrDataTypeEnum.PASSENGER_ID.getKey())); + } else if ("general_machine_invoice".equals(type) || "highway_passenger_invoice".equals(type) || "shipping_invoice".equals(type) || "passenger_transport_invoice".equals(type)) { + //为 general_machine_invoice(通用机打发票)、 highway_passenger_invoice(公路客运发票)、shipping_invoice(船运客票)、passenger_transport_invoice(旅客运输普票) + + // -------------航空运输电子客票行程单特殊字段-------------- + invoiceOcrData.setJSHJ(itemData.get(OcrDataTypeEnum.MONEY.getKey())); + invoiceOcrData.setFPDM(itemData.get(OcrDataTypeEnum.INVOICE_CODE.getKey())); + invoiceOcrData.setFPHM(itemData.get(OcrDataTypeEnum.INVOICE_NUMBER.getKey())); + invoiceOcrData.setKPRQ(itemData.get(OcrDataTypeEnum.DATE.getKey())); + invoiceOcrData.setSJ(itemData.get(OcrDataTypeEnum.TIME.getKey())); + } else if ("parking_invoice".equals(type)) { + invoiceOcrData.setJSHJ(itemData.get(OcrDataTypeEnum.MONEY.getKey())); + invoiceOcrData.setFPHM(itemData.get(OcrDataTypeEnum.INVOICE_NUMBER.getKey())); + } + + openServiceOcr.setRegion(ocrDataListEntity.getPosition()); + openServices.add(openServiceOcr); + } + return openServices; } } diff --git a/dxhy-core/src/main/java/com/dxhy/core/service/openservice/model/ocr/OcrDataListEntity.java b/dxhy-core/src/main/java/com/dxhy/core/service/openservice/model/ocr/OcrDataListEntity.java new file mode 100644 index 00000000..c46b2077 --- /dev/null +++ b/dxhy-core/src/main/java/com/dxhy/core/service/openservice/model/ocr/OcrDataListEntity.java @@ -0,0 +1,36 @@ +package com.dxhy.core.service.openservice.model.ocr; + + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +import java.util.List; + +@Data +public class OcrDataListEntity { + + @JsonProperty("image_angle") + private int imageAngle; + @JsonProperty("rotated_image_width") + private int rotatedImageWidth; + @JsonProperty("rotated_image_height") + private int rotatedImageHeight; + private String type; + @JsonProperty("type_description") + private String typeDescription; + //头信息 + @JsonProperty("item_list") + private List itemList; + //发票明细数据 + @JsonProperty("product_list") + private List> productList; + + //特殊字符无法作为常量key + private String CLASS; + private String kind; + @JsonProperty("kind_description") + private String kindDescription; + private List position; + + private String image; +} diff --git a/dxhy-core/src/main/java/com/dxhy/core/service/openservice/model/ocr/OcrDataTypeEnum.java b/dxhy-core/src/main/java/com/dxhy/core/service/openservice/model/ocr/OcrDataTypeEnum.java new file mode 100644 index 00000000..1ca4a7af --- /dev/null +++ b/dxhy-core/src/main/java/com/dxhy/core/service/openservice/model/ocr/OcrDataTypeEnum.java @@ -0,0 +1,197 @@ +package com.dxhy.core.service.openservice.model.ocr; + +import lombok.AllArgsConstructor; + +@AllArgsConstructor +public enum OcrDataTypeEnum { + + //➢type 为 vat_special_invoice(增值税专用发票)、vat_electronic_invoice(增 + //值税电子普通发票)、vat_common_invoice(增值税普通发票)、 + //vat_electronic_toll_invoice(增值税电子普通发票(通行费)) + VAT_INVOICE_CORRECT_CODE("vat_invoice_correct_code","校验码"), + VAT_INVOICE_DAIMA ("vat_invoice_daima","发票代码"), + VAT_INVOICE_HAOMA("vat_invoice_haoma","发票号码"), + VAT_INVOICE_HAOMA_LARGE_SIZE("vat_invoice_haoma_large_size","字体较大的发票号码"), + VAT_INVOICE_ISSUE_DATE("vat_invoice_issue_date","开票日期"), + VAT_INVOICE_RATE_PAYER_ID("vat_invoice_rate_payer_id","购买方纳税人识别号"), + VAT_INVOICE_TOTAL("vat_invoice_total","合计"), + VAT_INVOICE_TAX_RATE("vat_invoice_tax_rate","税率"), + VAT_INVOICE_JIDA_HAOMA("vat_invoice_jida_haoma","机打号码"), + VAT_INVOICE_SELLER_NAME("vat_invoice_seller_name","销售方名称"), + VAT_INVOICE_SELLER_BANK_ACCOUNT("vat_invoice_seller_bank_account","销售方开户行及帐号"), + VAT_INVOICE_SELLER_ID ("vat_invoice_seller_id","销售方纳税人识别号"), + VAT_INVOICE_SELLER_ADDR_TELL ("vat_invoice_seller_addr_tell","销售方地址、电话"), + VAT_INVOICE_PAYER_NAME ("vat_invoice_payer_name","购买方名称"), + VAT_INVOICE_PAYER_BANK_ACCOUNT ("vat_invoice_payer_bank_account","购买方开户行及帐号"), + VAT_INVOICE_PAYER_ADDR_TELL ("vat_invoice_payer_addr_tell","购买方地址、电话"), + VAT_INVOICE_TOTAL_COVER_TAX ("vat_invoice_total_cover_tax","价税合计大写"), + VAT_INVOICE_TOTAL_COVER_TAX_DIGITS ("vat_invoice_total_cover_tax_digits","价税合计小写"), + VAT_INVOICE_HEADLINE_PAGE_NUMBER ("vat_invoice_headline_page_number","标题发票联(普票,电子发票,专票增加字段)"), + VAT_INVOICE_TOTAL_PRINT ("vat_invoice_total_print","打印合计(普票,电子发票,专票增加字段)"), + VAT_INVOICE_CORRENT_CODE_PRINT ("vat_invoice_corrent_code_print","打印校验码(普票,电子发票,专票增加字段)"), + VAT_INVOICE_TAX_TOTAL("vat_invoice_tax_total","税额合计"), + VAT_INVOICE_GOODS_LIST ("vat_invoice_goods_list","货物或服务名称"), + VAT_INVOICE_GOODS("vat_invoice_goods","货物或服务名称"), + VAT_INVOICE_PRICE_LIST ("vat_invoice_price_list","金额明细"), + VAT_INVOICE_PRICE ("vat_invoice_price","金额明细"), + VAT_INVOICE_TAX_RATE_LIST ("vat_invoice_tax_rate_list","税率明细"), + VAT_INVOICE_TAX_LIST ("vat_invoice_tax_list","税额明细"), + VAT_INVOICE_TAX ("vat_invoice_tax","税额明细"), + VAT_INVOICE_ZHUAN_YONG_FLAG ("vat_invoice_zhuan_yong_flag","专票/普票/区块链发票"), + VAT_INVOICE_DAI_KAI_FLAG ("vat_invoice_dai_kai_flag","代开(非代开条目为空)"), + VAT_INVOICE_PLATE_SPECIFIC("vat_invoice_plate_specific","规格型号明细"), + VAT_INVOICE_ELECTRANS_UNIT ("vat_invoice_electrans_unit","单位明细"), + VAT_INVOICE_ELECTRANS_QUANTITY("vat_invoice_electrans_quantity","数量明细"), + VAT_INVOICE_ELECTRANS_UNIT_PRICE ("vat_invoice_electrans_unit_price","单价明细"), + VAT_INVOICE_DAIMA_RIGHT_SIDE ("vat_invoice_daima_right_side","右侧打印发票代码"), + VAT_INVOICE_HAOMA_RIGHT_SIDE ("vat_invoice_haoma_right_side","右侧打印发票号码"), + VAT_INVOICE_PAGE_NUMBER ("vat_invoice_page_number","抵扣联/发票联"), + VAT_INVOICE_TYPE ("vat_invoice_type","发票类型"), + VAT_INVOICE_TOTAL_NOTE ("vat_invoice_total_note","备注"), + VAT_INVOICE_CIPHER_FIELD ("vat_invoice_cipher_field","密码区"), + VAT_INVOICE_DRAWER ("vat_invoice_drawer","开票人"), + VAT_INVOICE_REVIEW ("vat_invoice_review","复核人"), + VAT_INVOICE_PAYEE ("vat_invoice_payee","收款人"), + EXIST_STAMPLE("exist_stample","盖章存在性判断"), + + VEHICLE_INVOICE_BUYER("vehicle_invoice_buyer","购买方名称"), + VEHICLE_INVOICE_BUYER_ID ("vehicle_invoice_buyer_id","购买方名称的身份证号码或组织机构代码"), + VEHICLE_INVOICE_CAR_MODEL ("vehicle_invoice_car_model","厂牌型号"), + VEHICLE_INVOICE_CAR_MADE_PLACE("vehicle_invoice_car_made_place","产地"), + VEHICLE_INVOICE_CERT_ID ("vehicle_invoice_cert_id","合格证号"), + VEHICLE_INVOICE_ENGINE_ID ("vehicle_invoice_engine_id","发动机号码"), + VEHICLE_INVOICE_CAR_VIN("vehicle_invoice_car_vin","车辆识别代号/车架号"), + VEHICLE_INVOICE_TOTAL_PRICE("vehicle_invoice_total_price","价税合计"), + VEHICLE_INVOICE_TOTAL_PRICE_DIGITS("vehicle_invoice_total_price_digits","价税合计小写"), + VEHICLE_INVOICE_PRICE_WITHOUT_TAX("VEHICLE_INVOICE_PRICE_WITHOUT_TAX","不含税价"), + VEHICLE_INVOICE_TAX_RATE("vehicle_invoice_tax_rate","税率"), + VEHICLE_INVOICE_TAX_AMOUNT ("vehicle_invoice_tax_amount","税额"), + VEHICLE_INVOICE_TELEPHONE ("vehicle_invoice_telephone","电话"), + VEHICLE_INVOICE_ISSUE_DATE("vehicle_invoice_issue_date","开票日期"), + VEHICLE_INVOICE_DAIMA("vehicle_invoice_daima","发票代码"), + VEHICLE_INVOICE_HAOMA("vehicle_invoice_haoma","发票号码"), + VEHICLE_INVOICE_DEALER("vehicle_invoice_dealer","销货单位"), + VEHICLE_INVOICE_JIDA_DAIMA ("vehicle_invoice_jida_daima","机打代码"), + VEHICLE_INVOICE_JIDA_HAOMA ("vehicle_invoice_jida_haoma","机打号码"), + VEHICLE_INVOICE_MACHINE_ID ("vehicle_invoice_machine_id","机器编码"), + VEHICLE_INVOICE_TAX_AUTHORITH_ID("vehicle_invoice_tax_authorith_id","主管税务代码"), + VEHICLE_INVOICE_TAX_AUTHORITH ("vehicle_invoice_tax_authorith","主管税务机关"), + VEHICLE_INVOICE_SELLER_BANK_NAME ("vehicle_invoice_seller_bank_name","开户银行"), + VEHICLE_INVOICE_SELLER_BANK_ACCOUNT("vehicle_invoice_seller_bank_account","账号"), + VEHICLE_INVOICE_SELLER_TAX_ID ("vehicle_invoice_seller_tax_id","纳税人识别号"), + VEHICLE_INVOICE_COMMODITY_INSPECTION_ID ("vehicle_invoice_commodity_inspection_id","商检单号"), + VEHICLE_INVOICE_IMPORT_CERTIFICATE_ID ("vehicle_invoice_import_certificate_id","进口证明书号"), + VEHICLE_INVOICE_SELLER_ADDRESS ("vehicle_invoice_seller_address","地址"), + +// vehicle_invoice_daima("vehicle_invoice_daima","购车发票代码"), +// vehicle_invoice_haoma ("vehicle_invoice_haoma","购车发票号码"), +// vehicle_invoice_buyer ("vehicle_invoice_buyer","购货单位(人)"), +// vehicle_invoice_buyer_id ("vehicle_invoice_buyer_id","购买身份证号码/组织机构代码"), + VEHICLE_INVOICE_BUYER_ADDR("vehicle_invoice_buyer_addr","购买方地址"), + VEHICLE_INVOICE_BUYER_PHONE ("vehicle_invoice_buyer_phone","购买方电话号码"), + VEHICLE_INVOICE_SELLER ("vehicle_invoice_seller","卖方单位(人)"), + VEHICLE_INVOICE_SELLER_ID ("vehicle_invoice_seller_id","买方身份证号码/组织机构代码"), + VEHICLE_INVOICE_SELLER_ADDR ("vehicle_invoice_seller_addr","卖方地址"), + VEHICLE_INVOICE_SELLER_PHONE ("vehicle_invoice_seller_phone","卖方电话号码"), + VEHICLE_INVOICE_PLATE_NUM ("vehicle_invoice_plate_num","车牌照号"), + VEHICLE_INVOICE_REGISTER_NUM("vehicle_invoice_register_num","登记证号"), + VEHICLE_INVOICE_VEHICLE_TYPE ("vehicle_invoice_vehicle_type","车辆类型"), + VEHICLE_INVOICE_VIN ("vehicle_invoice_vin","车架号/车辆识别代码"), +// vehicle_invoice_car_model("vehicle_invoice_car_model","厂牌型号"), + VEHICLE_INVOICE_DMV("vehicle_invoice_dmv","转入地车辆管理所名称"), + VEHICLE_INVOICE_PRICE_TOTAL_PRICE ("vehicle_invoice_price_total_price","价税合计"), +// vehicle_invoice_total_price_digits ("vehicle_invoice_total_price_digits","价税合计小写"), + VEHICLE_INVOICE_AUCTION_HOUSE ("vehicle_invoice_auction_house","经营、拍卖单位"), + VEHICLE_INVOICE_AUCTION_HOUSE_ADDR("vehicle_invoice_auction_house_addr","经营、拍卖单位地址"), + VEHICLE_INVOICE_AUCTION_HOUSE_TAX_ID ("vehicle_invoice_auction_house_tax_id","经营、拍卖单位纳税人识别号"), + VEHICLE_INVOICE_AUCTION_HOUSE_BANK_ACCOUNT ("vehicle_invoice_auction_house_bank_account","经营、拍卖单位开户银行、账号"), + VEHICLE_INVOICE_AUCTION_HOUSE_PHONE ("vehicle_invoice_auction_house_phone","经营、拍卖单位电话"), + VEHICLE_INVOICE_MARKET ("vehicle_invoice_market","二手车市场"), + VEHICLE_INVOICE_MARKET_ADDR ("vehicle_invoice_market_addr","二手车市场地址"), + VEHICLE_INVOICE_MARKET_TAX_ID ("vehicle_invoice_market_tax_id","二手车市场纳税人识别号"), + VEHICLE_INVOICE_MARKET_BANK_ACOUNT ("vehicle_invoice_market_bank_acount","二手车市场开户银行、账号"), + VEHICLE_INVOICE_MARKET_PHONE ("vehicle_invoice_market_phone","二手车市场电话"), + VEHICLE_INVOICE_NOTE ("vehicle_invoice_note","备注"), +// vehicle_invoice_issue_date ("vehicle_invoice_issue_date","购车发票开票日期"), + + INVOICE_HEAD("invoice_head","发票票头"), + INVOICE_NUMBER("invoice_number","发票号码"), + INVOICE_CODE("invoice_code","发票代码"), + MACHINE_NUMBER ("machine_number","机器号码"), + MACHINE_CODE ("machine_code","机器编码"), + TOTAL_MONEY("total_money","合计金额(小写)"), + TOTAL_MONEY_BIG ("total_money_big","合计金额(大写)"), + DATE_OF_INVOICE ("date_of_invoice","开票日期"), + CHECK_NUMBER ("check_number","校验码"), + BUY_NAME("buy_name","购方名称"), + BUY_TAX_NUMBER("buy_tax_number","购方纳税人识别号"), + SOLD_NAME ("sold_name","销方名称"), + SOLD_TAX_NUMBER ("sold_tax_number","销方纳税人识别号"), + CASHIER_NAME ("cashier_name","收款员"), + + QUOTA_INVOICE_CODE("quota_invoice_code","发票代码"), + QUOTA_INVOICE_NUMBER ("quota_invoice_number","发票号码"), + MONEY_SMALL ("money_small","金额(小写)"), + MONEY_BIG ("money_big","金额(大写)"), + LOCATION ("location","发票所在地"), + +// invoice_code ("invoice_code","发票代码"), + INVOICE_NO ("invoice_no","发票号码"), + DATE ("date","日期"), + TAXI_NO ("taxi_no","车号"), + BOARDING_TIME("boarding_time","上车时间"), + LANDING_TIME ("landing_time","下车时间"), + MILEAGE ("mileage","里程"), + SUM ("sum","金额"), +// location ("location","发票所在地"), + + PASSENGER_NAME ("passenger_name","旅客姓名"), + ID_NO ("id_no","身份证件号码"), + SERIAL_NUMBER ("serial_number","印刷序号"), + TOTAL("total","合计金额"), + FARE ("fare","票价"), + CIVIL_AVIATION_FUND ("civil_aviation_fund","民航发展基金"), + FUEL_SURCHARGE ("fuel_surcharge","燃油附加费"), + OTHER_TAXES("other_taxes","其他税费"), + ISSUED_DATE ("issued_date","填开日期"), + ISSUED_BY ("issued_by","填开单位"), + E_TICKET_NO ("e_ticket_no","电子客票号码"), + INSURANCE ("insurance","保险费"), + +// passenger_name("passenger_name","乘客名称"), + PASSENGER_ID("passenger_id","乘客身份证"), + TRAIN_NUMBER ("train_number","车次号"), + DEPARTURE_STATION ("departure_station","出发地"), + DEPARTURE_DATE ("departure_date","乘车时间"), + //TODO + CLASS ("class","座位类别"), + TICKET_NUMBER ("ticket_number","火车票红色编码"), + ARRIVAL_STATION ("arrival_station","目的地"), + SEAT_NUMBER ("seat_number","座位号"), + PRICE ("price","价格"), + CHECK ("check","检票口"), + TICKET_ID ("ticket_id","火车票ID"), + + + +// invoice_code ("invoice_code","发票代码"), +// invoice_number ("invoice_number","发票号码"), + MONEY ("money","金额"), +// date ("date","日期"), + TIME ("time","时间"), + TOLL_CODE ("toll_code","车辆通行费代码"), + TOLL_NUMBER ("toll_number","车辆通行费号码"), + + +// invoice_number ("invoice_number","发票号码"), +// money ("money","金额"), + + ; + private String key; + + private String value; + + public String getKey() { + return key; + } +} diff --git a/dxhy-core/src/main/java/com/dxhy/core/service/openservice/model/ocr/OcrItemListEntity.java b/dxhy-core/src/main/java/com/dxhy/core/service/openservice/model/ocr/OcrItemListEntity.java new file mode 100644 index 00000000..b2c62d43 --- /dev/null +++ b/dxhy-core/src/main/java/com/dxhy/core/service/openservice/model/ocr/OcrItemListEntity.java @@ -0,0 +1,13 @@ +package com.dxhy.core.service.openservice.model.ocr; + +import lombok.Data; + +import java.util.List; + +@Data +public class OcrItemListEntity { + private String value; + private String description; + private String key; + private List position; +} diff --git a/dxhy-core/src/main/java/com/dxhy/core/service/openservice/model/ocr/OcrProductListEntity.java b/dxhy-core/src/main/java/com/dxhy/core/service/openservice/model/ocr/OcrProductListEntity.java new file mode 100644 index 00000000..642e51e3 --- /dev/null +++ b/dxhy-core/src/main/java/com/dxhy/core/service/openservice/model/ocr/OcrProductListEntity.java @@ -0,0 +1,12 @@ +package com.dxhy.core.service.openservice.model.ocr; + +import lombok.Data; + +import java.util.List; + +@Data +public class OcrProductListEntity { + private String description; + private String key; + private String value; +} diff --git a/dxhy-core/src/main/java/com/dxhy/core/service/openservice/model/ocr/OcrResponseVo.java b/dxhy-core/src/main/java/com/dxhy/core/service/openservice/model/ocr/OcrResponseVo.java new file mode 100644 index 00000000..b4546b88 --- /dev/null +++ b/dxhy-core/src/main/java/com/dxhy/core/service/openservice/model/ocr/OcrResponseVo.java @@ -0,0 +1,15 @@ +package com.dxhy.core.service.openservice.model.ocr; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +@Data +public class OcrResponseVo { + + + private OcrResultEntity result; + @JsonProperty("cost_time") + private int costTime; + private int code; + private String message; +} diff --git a/dxhy-core/src/main/java/com/dxhy/core/service/openservice/model/ocr/OcrResultEntity.java b/dxhy-core/src/main/java/com/dxhy/core/service/openservice/model/ocr/OcrResultEntity.java new file mode 100644 index 00000000..c284ae56 --- /dev/null +++ b/dxhy-core/src/main/java/com/dxhy/core/service/openservice/model/ocr/OcrResultEntity.java @@ -0,0 +1,14 @@ +package com.dxhy.core.service.openservice.model.ocr; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +import java.util.List; + +@Data +public class OcrResultEntity { + + @JsonProperty("object_list") + private List objectList; + +} From 24923e6da20d9fb3bb7fca1f21a9678ae6e26d47 Mon Sep 17 00:00:00 2001 From: "zhenghaiyang@ele-cloud.com" Date: Sat, 18 Mar 2023 14:58:59 +0800 Subject: [PATCH 2/7] =?UTF-8?q?feature=201.=E8=AE=A4=E8=AF=81=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=E6=8E=A5=E5=8F=A3=E6=94=B9=E9=80=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/BaseInvoiceController.java | 10 +++++++ .../base/entity/BaseTDxRecordInvoice.java | 10 +++++++ .../com/dxhy/base/model/BaseFpRzRespVO.java | 13 +++++++++ .../main/resources/mapper/BaseFpZhMapper.xml | 28 +++++++++++++++---- 4 files changed, 56 insertions(+), 5 deletions(-) diff --git a/dxhy-base/src/main/java/com/dxhy/base/controller/BaseInvoiceController.java b/dxhy-base/src/main/java/com/dxhy/base/controller/BaseInvoiceController.java index 502ee0f3..eba93093 100644 --- a/dxhy-base/src/main/java/com/dxhy/base/controller/BaseInvoiceController.java +++ b/dxhy-base/src/main/java/com/dxhy/base/controller/BaseInvoiceController.java @@ -130,6 +130,16 @@ public class BaseInvoiceController extends AbstractController { int curr = (int)map.get("curr"); int size = (int)map.get("size"); Map pramsMap = new HashMap<>(25); + + pramsMap.put("qszt", map.get("qszt")); + pramsMap.put("wrzfpStart", map.get("wrzfpStart")); + pramsMap.put("wrzfpEnd", map.get("wrzfpEnd")); + pramsMap.put("imageNumber", map.get("imageNumber")); + pramsMap.put("postingTimeStart", map.get("postingTimeStart")); + pramsMap.put("postingTimeEnd", map.get("postingTimeEnd")); + pramsMap.put("accountPeriodStart", map.get("accountPeriodStart")); + pramsMap.put("accountPeriodEnd", map.get("accountPeriodEnd")); + pramsMap.put("snVoucherNumber", map.get("snVoucherNumber")); pramsMap.put("company", map.get("company")); pramsMap.put("menuId", map.get("menuId")); pramsMap.put("xfmc", xfmc); diff --git a/dxhy-base/src/main/java/com/dxhy/base/entity/BaseTDxRecordInvoice.java b/dxhy-base/src/main/java/com/dxhy/base/entity/BaseTDxRecordInvoice.java index 2fd4096d..76c091e0 100644 --- a/dxhy-base/src/main/java/com/dxhy/base/entity/BaseTDxRecordInvoice.java +++ b/dxhy-base/src/main/java/com/dxhy/base/entity/BaseTDxRecordInvoice.java @@ -466,4 +466,14 @@ public class BaseTDxRecordInvoice implements Serializable { private String inAccountStatus; private String invoiceSource; + + //凭证号 + private String snVoucherNumber; + //账期 + private Date accountPeriod; + //过账时间 + private Date postingTime; + + + } diff --git a/dxhy-base/src/main/java/com/dxhy/base/model/BaseFpRzRespVO.java b/dxhy-base/src/main/java/com/dxhy/base/model/BaseFpRzRespVO.java index 517d1f8a..da7fbd30 100644 --- a/dxhy-base/src/main/java/com/dxhy/base/model/BaseFpRzRespVO.java +++ b/dxhy-base/src/main/java/com/dxhy/base/model/BaseFpRzRespVO.java @@ -1,7 +1,9 @@ package com.dxhy.base.model; import java.io.Serializable; +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; import lombok.Data; /** @@ -187,4 +189,15 @@ public class BaseFpRzRespVO implements Serializable { public BaseFpRzRespVO() {} + //凭证号 SN + private String snVoucherNumber; + //账期 SN + @JsonFormat(pattern = "yyyy-MM-dd", locale = "zh", timezone="GMT+8") + private Date accountPeriod; + //过账时间 SN + @JsonFormat(pattern = "yyyy-MM-dd", locale = "zh", timezone="GMT+8") + private Date postingTime; + //影像号 SN + private String imageNumber; + } diff --git a/dxhy-base/src/main/resources/mapper/BaseFpZhMapper.xml b/dxhy-base/src/main/resources/mapper/BaseFpZhMapper.xml index a9f4583d..d54a78f0 100644 --- a/dxhy-base/src/main/resources/mapper/BaseFpZhMapper.xml +++ b/dxhy-base/src/main/resources/mapper/BaseFpZhMapper.xml @@ -60,7 +60,7 @@ dqskssq,t.auth_status,t.qs_type,t.qs_status,t.confirm_user,t.qs_name,t.rzh_yesorno,t.cxrz_status,t.out_status, t.bdk_status,t.bdk_current_period,date_format(t.bdk_date,'%Y-%m-%d') bdk_date,t.rzh_back_msg,t.in_account_status,t.payment_status,date_format(t.payment_date,'%Y-%m-%d')payment_date, - voucher_number + voucher_number, sn_voucher_number, account_period, posting_time ,image_number from t_dx_record_invoice t WHERE date_format(t.invoice_date,'%Y-%m-%d') between #{kpksrq} and #{kpjsrq} @@ -84,16 +84,31 @@ and t.qs_type = #{qsfs} - + + and t.qs_status = #{qszt} + + + and rzh_yesorno = '0' and date_format(t.invoice_date,'%Y-%m-%d') between #{wrzfpStart} and #{wrzfpEnd} + + and date_format(t.qs_date,'%Y-%m-%d') between #{qsksrq} and #{qsjsrq} - + and date_format(t.rzh_date,'%Y-%m-%d') between #{rzksrq} and #{rzjsrq} + + + and date_format(t.account_period,'%Y-%m') between #{accountPeriodStart} and #{accountPeriodEnd} + + + and date_format(t.posting_time,'%Y-%m-%d') between #{postingTimeStart} and #{postingTimeEnd} and t.rzh_yesorno = #{rzzt} + + + and t.image_number = #{imageNumber} and t.auth_status = #{rzclzt} @@ -145,6 +160,9 @@ and t.rzh_belong_date = #{skssq} + + + and t.sn_voucher_number = #{snVoucherNumber} From 37d5e3eb714a080cf4f3970fea6ab45aff8980a2 Mon Sep 17 00:00:00 2001 From: "zhenghaiyang@ele-cloud.com" Date: Mon, 20 Mar 2023 15:58:02 +0800 Subject: [PATCH 3/7] =?UTF-8?q?feature=201.=E5=8F=91=E7=A5=A8=E7=AD=BE?= =?UTF-8?q?=E6=94=B6=E5=AE=9A=E5=88=B6=E5=8C=96=E5=8A=9F=E8=83=BD=E5=BC=80?= =?UTF-8?q?=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dxhy/sign/config/BaseServiceConfig.java | 43 +++++ .../com/dxhy/sign/config/ExcelConverter.java | 153 ++++++++++++++++++ .../sign/controller/SignFpqsController.java | 42 ++++- .../com/dxhy/sign/entity/QsExcelEntity.java | 93 +++++++++++ .../sign/service/fpqs/SignFpqsService.java | 3 + .../fpqs/impl/SignFpqsServiceImpl.java | 135 +++++++++++++++- .../mapper/SignRecordInvoiceMapper.xml | 6 + 7 files changed, 473 insertions(+), 2 deletions(-) create mode 100644 dxhy-sign/src/main/java/com/dxhy/sign/config/BaseServiceConfig.java create mode 100644 dxhy-sign/src/main/java/com/dxhy/sign/config/ExcelConverter.java create mode 100644 dxhy-sign/src/main/java/com/dxhy/sign/entity/QsExcelEntity.java diff --git a/dxhy-sign/src/main/java/com/dxhy/sign/config/BaseServiceConfig.java b/dxhy-sign/src/main/java/com/dxhy/sign/config/BaseServiceConfig.java new file mode 100644 index 00000000..5ae63a07 --- /dev/null +++ b/dxhy-sign/src/main/java/com/dxhy/sign/config/BaseServiceConfig.java @@ -0,0 +1,43 @@ +package com.dxhy.sign.config; + + +import lombok.Data; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Configuration; + +@Data +@Configuration +public class BaseServiceConfig { + + /** + * 客户自定义邮件配置-发件人邮箱地址 + */ + @Value("${order.email.customer.sendAddress:}") + private String sendAddress; + /** + * 客户自定义邮件配置-第三方支持授权码(126和163以及qq邮箱都需要授权码登录,没有授权码的直接登录网页版邮箱设置里设置) + * 如果是其他企业邮箱,直接使用邮箱登录密码 + */ + @Value("${order.email.customer.authPassword:}") + private String authPassword; + /** + * 客户自定义邮件配置-发件人名称 + */ + @Value("${order.email.customer.sendName:}") + private String sendName; + /** + * 客户自定义邮件配置-邮件服务器 + */ + @Value("${order.email.customer.smtpServer:}") + private String smtpServer; + + /** + * 客户自定义邮件配置-邮件服务器端口 + */ + @Value("${order.email.customer.sslPort:}") + private String sslPort; + + + + +} diff --git a/dxhy-sign/src/main/java/com/dxhy/sign/config/ExcelConverter.java b/dxhy-sign/src/main/java/com/dxhy/sign/config/ExcelConverter.java new file mode 100644 index 00000000..d2cb9cd4 --- /dev/null +++ b/dxhy-sign/src/main/java/com/dxhy/sign/config/ExcelConverter.java @@ -0,0 +1,153 @@ +//package com.dxhy.sign.config; +// +//import com.alibaba.excel.metadata.CellData; +//import com.alibaba.excel.metadata.Head; +//import com.alibaba.excel.write.handler.CellWriteHandler; +//import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; +//import com.alibaba.excel.write.metadata.holder.WriteTableHolder; +//import org.apache.poi.hssf.usermodel.HSSFDataFormat; +//import org.apache.poi.ss.usermodel.*; +// +//import java.util.List; +// +///** +// * Created by IntelliJ IDEA. +// * +// * @author: zhenghaiyang +// * Date: 2021/12/22 0022 +// * Description: +// */ +//public class ExcelConverter implements CellWriteHandler{ +// +// +// @Override +// public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer integer, Integer integer1, Boolean aBoolean) { +// System.out.println(); +// } +// +// @Override +// public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, Integer integer, Boolean aBoolean) { +// +// //当前行的第i列 +// // int i = cell.getColumnIndex(); +// //不处理第一行 +// if (0 != cell.getRowIndex()) { +// if (2 == cell.getColumnIndex()) { +// Workbook workbook = writeSheetHolder.getSheet().getWorkbook(); +// CellStyle cellStyle = workbook.createCellStyle(); +// DataFormat dataFormat = workbook.createDataFormat(); +// cellStyle.setDataFormat(HSSFDataFormat.getBuiltinFormat("0.00")); +// cell.setCellStyle(cellStyle); +// } +// } +// } +// +// //加@Override会报错 +// public void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, CellData cellData, Cell cell, Head head, Integer integer, Boolean aBoolean) { +// +// System.out.println(); +// } +// +// @Override +// public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List list, Cell cell, Head head, Integer integer, Boolean aBoolean) { +// CellStyle cellStyle = cell.getSheet().getWorkbook().createCellStyle(); +// final CellType cellType = cell.getCellType(); +// +// if(CellType.NUMERIC.equals(cellType)){ +// final double cellValue = cell.getNumericCellValue(); +// final String valueOf = String.valueOf(cellValue); +// //判断data是否为数值型 +// Boolean isNum = valueOf.matches("^(-?\\d+)(\\.\\d+)?$"); +// //判断data是否为整数(小数部分是否为0) +// Boolean isInteger=valueOf.matches("^(\\-)?\\d+(\\.\\d{1,2})$"); +// //判断data是否为百分数(是否包含“%”) +// Boolean isPercent=valueOf.matches("^(\\-)?\\d+(\\.\\d{8})$"); +// if(isNum){ +// if(isInteger){ +// DataFormat dataFormat = cell.getSheet().getWorkbook().createDataFormat(); +// cellStyle.setDataFormat(dataFormat.getFormat("0.00_ ")); +// cell.setCellStyle(cellStyle); +// }else { +// DataFormat dataFormat = cell.getSheet().getWorkbook().createDataFormat(); +// cellStyle.setDataFormat(dataFormat.getFormat("0.00000000_ ")); +// cell.setCellStyle(cellStyle); +// } +// } +// } +// } +// +//// +//// @Override +//// public Class supportJavaTypeKey(){ +//// return Double.class; +//// } +//// +//// @Override +//// public CellDataTypeEnum supportExcelTypeKey(){ +//// return CellDataTypeEnum.STRING; +//// } +//// +//// @Override +//// public Object convertToJavaData(CellData cellData, ExcelContentProperty excelContentProperty, GlobalConfiguration globalConfiguration) throws Exception{ +//// +//// return null; +//// } +//// +//// @Override +//// public CellData convertToExcelData(Object o, ExcelContentProperty excelContentProperty, +//// GlobalConfiguration globalConfiguration) throws Exception{ +//// try{ +//// if(o != null){ +//// +//// final CellData cellData = new CellData(CellDataTypeEnum.NUMBER); +//// cellData.setDataFormatString("##,##0.00"); +//// cellData.setNumberValue(new BigDecimal(String.valueOf(o))); +//// return cellData; +//// } +//// }catch(NumberFormatException e){ +//// e.printStackTrace(); +//// } +//// return null; +//// } +// +//// +//// @Override +//// public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, +//// Head head, Integer integer, Integer integer1, Boolean aBoolean){ +//// +//// } +//// +//// @Override +//// public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, +//// Head head, Integer integer, Boolean aBoolean){ +//// +//// } +//// +//// @Override +//// public void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, CellData cellData, Cell cell, Head head, Integer integer, Boolean aBoolean){ +//// +//// } +// +//// @Override +//// public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { +//// CellStyle cellStyle = cell.getSheet().getWorkbook().createCellStyle(); +//// cellStyle.setFillForegroundColor(IndexedColors.SKY_BLUE.index); +//// cellStyle.setFillBackgroundColor(IndexedColors.WHITE.index); +//// cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); +//// +//// cellStyle.setBorderLeft(BorderStyle.THIN); +//// cellStyle.setBorderTop(BorderStyle.THIN); +//// cellStyle.setBorderRight(BorderStyle.THIN); +//// cellStyle.setBorderBottom(BorderStyle.THIN); +//// +//// DataFormat dataFormat = cell.getSheet().getWorkbook().createDataFormat(); +//// cellStyle.setDataFormat(dataFormat.getFormat("##,##0.00")); +//// cell.setCellStyle(cellStyle); +//// } +//// +//// public CellStyle getStyles(boolean noneStyler, ExcelExportEntity entity) { +//// if(entity != null && ){ +//// +//// } +//// } +//} diff --git a/dxhy-sign/src/main/java/com/dxhy/sign/controller/SignFpqsController.java b/dxhy-sign/src/main/java/com/dxhy/sign/controller/SignFpqsController.java index 4bfb1673..a9753ce7 100644 --- a/dxhy-sign/src/main/java/com/dxhy/sign/controller/SignFpqsController.java +++ b/dxhy-sign/src/main/java/com/dxhy/sign/controller/SignFpqsController.java @@ -10,6 +10,10 @@ import java.util.Map; import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; +import com.alibaba.excel.EasyExcel; +import com.alibaba.excel.ExcelWriter; +import com.alibaba.excel.write.metadata.WriteSheet; +import com.dxhy.sign.entity.QsExcelEntity; import org.apache.commons.lang3.StringUtils; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; @@ -106,7 +110,11 @@ public class SignFpqsController extends AbstractController { int size = (int)pramsMap.get("size"); try { - return ResponseEntity.ok(R.ok().put("data", signFpqsService.selectWqsfp(pramsMap, curr, size))); + if(pramsMap.get("emailAddress") == null){ + return ResponseEntity.ok(R.ok().put("data", signFpqsService.selectWqsfp(pramsMap, curr, size))); + }else { + return ResponseEntity.ok(signFpqsService.qsSendEmail(pramsMap)); + } } catch (Exception e) { e.printStackTrace(); log.error("", e); @@ -114,6 +122,38 @@ public class SignFpqsController extends AbstractController { } } + @RequestMapping("/qsExport") + public void qsExport(@RequestBody Map pramsMap, HttpServletResponse response){ + List excelList = signFpqsService.selectWqsfp(pramsMap); + ExcelWriter excelWriter = null; + if(excelList != null){ + String fileName = "签收数据导出" + ".xlsx"; + ByteArrayOutputStream outputStream = null; + try { + response.setContentType("application/vnd.ms-excel"); + response.setCharacterEncoding("utf-8"); + response.setHeader("Content-disposition", "attachment;filename*=utf-8''"+fileName+".xlsx"); + excelWriter = EasyExcel.write(outputStream).build(); + WriteSheet writeSheet = EasyExcel.writerSheet("sheet1").head(QsExcelEntity.class).build(); + excelWriter.write(excelList, writeSheet); + }catch(Exception e){ + log.error("签收数据导出,错误日志:{}",e); + } finally { + // 千万别忘记finish 会帮忙关闭流 + if (excelWriter != null) { + excelWriter.finish(); + } + if(outputStream != null){ + try { + outputStream.close(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } + } + } + /** * 签收选定的未签收的发票 * diff --git a/dxhy-sign/src/main/java/com/dxhy/sign/entity/QsExcelEntity.java b/dxhy-sign/src/main/java/com/dxhy/sign/entity/QsExcelEntity.java new file mode 100644 index 00000000..3c2aa910 --- /dev/null +++ b/dxhy-sign/src/main/java/com/dxhy/sign/entity/QsExcelEntity.java @@ -0,0 +1,93 @@ +package com.dxhy.sign.entity; + +import com.alibaba.excel.annotation.ExcelProperty; +import com.alibaba.excel.annotation.write.style.ColumnWidth; +import com.alibaba.excel.annotation.write.style.ContentFontStyle; +import com.alibaba.excel.annotation.write.style.HeadFontStyle; +import com.alibaba.excel.annotation.write.style.HeadStyle; +import com.alibaba.excel.enums.poi.BorderStyleEnum; +import com.alibaba.excel.enums.poi.FillPatternTypeEnum; +import com.alibaba.excel.enums.poi.HorizontalAlignmentEnum; +import lombok.Data; +import org.apache.poi.ss.usermodel.BorderStyle; +import org.apache.poi.ss.usermodel.FillPatternType; +import org.apache.poi.ss.usermodel.HorizontalAlignment; + +import java.math.BigDecimal; +import java.util.Date; +import java.util.List; + + +@Data +@ColumnWidth(11) +@ContentFontStyle(fontHeightInPoints = 10) +@HeadFontStyle(fontHeightInPoints = 12,fontName = "等线") +@HeadStyle(borderTop = BorderStyleEnum.THIN,borderBottom = BorderStyleEnum.THIN,borderLeft = BorderStyleEnum.THIN, + borderRight = BorderStyleEnum.THIN,fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND,horizontalAlignment = + HorizontalAlignmentEnum.CENTER) +public class QsExcelEntity { + + //开票日期、销方单位名称、购方单位名称、发票代码、发票号码、不含税金额、税额、价税合计金额、备注,以上字段从发票中填充, + //签收人、签收日期取发票签收时的信息 + /** + * 开票日期 + */ + @ExcelProperty("开票日期") + private Date invoiceDate; + /** + * 购方名称 + */ + @ExcelProperty("销方单位名称") + private String gfName; + + /** + * 销方名称 + */ + @ExcelProperty("购方单位名称") + private String xfName; + /** + * 发票代码 + */ + @ExcelProperty("发票代码") + private String invoiceCode; + + /** + * 发票号码 + */ + @ExcelProperty("发票号码") + private String invoiceNo; + /** + * 金额 + */ + @ExcelProperty("不含税金额") + private String invoiceAmount; + + /** + * 税额 + */ + @ExcelProperty("税额") + private String taxAmount; + + /** + * 价格合计 + */ + @ExcelProperty("价税合计金额") + private String totalAmount; + /** + * 备注 + */ + @ExcelProperty("备注") + private String remark; + /** + * 签收人 + */ + @ExcelProperty("签收人") + private String qsName; + /** + * 签收时间 + */ + @ExcelProperty("签收时间") + private Date qsDate; + + +} diff --git a/dxhy-sign/src/main/java/com/dxhy/sign/service/fpqs/SignFpqsService.java b/dxhy-sign/src/main/java/com/dxhy/sign/service/fpqs/SignFpqsService.java index 3ce4a5b8..f828d6e4 100644 --- a/dxhy-sign/src/main/java/com/dxhy/sign/service/fpqs/SignFpqsService.java +++ b/dxhy-sign/src/main/java/com/dxhy/sign/service/fpqs/SignFpqsService.java @@ -8,6 +8,7 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.dxhy.common.service.MpBaseService; import com.dxhy.common.vo.UserInfo; +import com.dxhy.sign.entity.QsExcelEntity; import com.dxhy.sign.entity.TDxRecordInvoice; import com.dxhy.sign.entity.TDxRecordInvoiceStatistics; @@ -34,6 +35,8 @@ public interface SignFpqsService extends MpBaseService { * */ String selectWqsfp(Map pramsMap, int curr, int size); + List selectWqsfp(Map pramsMap); + String qsSendEmail(Map pramsMap); /** * 签收未签收的发票 diff --git a/dxhy-sign/src/main/java/com/dxhy/sign/service/fpqs/impl/SignFpqsServiceImpl.java b/dxhy-sign/src/main/java/com/dxhy/sign/service/fpqs/impl/SignFpqsServiceImpl.java index ed9d4d37..7906c312 100644 --- a/dxhy-sign/src/main/java/com/dxhy/sign/service/fpqs/impl/SignFpqsServiceImpl.java +++ b/dxhy-sign/src/main/java/com/dxhy/sign/service/fpqs/impl/SignFpqsServiceImpl.java @@ -1,14 +1,31 @@ package com.dxhy.sign.service.fpqs.impl; +import java.io.ByteArrayOutputStream; +import java.io.FileOutputStream; +import java.io.IOException; import java.math.BigDecimal; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.*; import javax.annotation.Resource; - +import javax.servlet.ServletOutputStream; + +import cn.hutool.core.codec.Base64Decoder; +import cn.hutool.core.util.ArrayUtil; +import com.alibaba.excel.EasyExcel; +import com.alibaba.excel.ExcelWriter; +import com.alibaba.excel.write.metadata.WriteSheet; +import com.dxhy.base.sms.utils.MessageSenderUtil; +import com.dxhy.base.sms.vo.AttachmentVo; +import com.dxhy.base.sms.vo.MailContentVo; +import com.dxhy.base.sms.vo.SendMailVo; +import com.dxhy.sign.config.BaseServiceConfig; +import com.google.common.collect.Lists; import org.apache.commons.lang3.StringUtils; import org.joda.time.DateTime; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -53,6 +70,7 @@ import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import lombok.extern.slf4j.Slf4j; +import sun.security.krb5.internal.PAData; /** * 发票签收业务逻辑处理实现类 @@ -3292,4 +3310,119 @@ public class SignFpqsServiceImpl extends MpBaseServiceImpl selectWqsfp(Map pramsMap) { + DynamicContextHolder.push(pramsMap.get("dbName") + DbConstant.BUSINESS_READ); + if(pramsMap.get("ids") != null){ + String[] ids = String.valueOf(pramsMap.get("ids")).split(","); + List strings = Arrays.asList(ids); + pramsMap.put("ids",strings); + } + List pageList = super.baseMapper.selectWqsfp(pramsMap); + PageInfo pageInfo = new PageInfo<>(pageList); + List resultList = pageInfo.getList(); + List excelList = Lists.newArrayList(); + if (resultList != null && resultList.size() > 0) { + for (int i = 0; i < resultList.size(); i++) { + QsExcelEntity qsExcelEntity = new QsExcelEntity(); + BeanUtils.copyProperties(qsExcelEntity,resultList.get(i)); + qsExcelEntity.setInvoiceAmount(AmountFormatUtil.fmtMicrometer(MathUtil.round(resultList.get(i).getTotalAmount().toPlainString()))); + excelList.add(qsExcelEntity); + } + } + return excelList; + } + + public String qsSendEmail(Map pramsMap){ + List excelList = selectWqsfp(pramsMap); + ExcelWriter excelWriter = null; + if(excelList != null){ +// String fileName = "签收数据导出" + ".xlsx"; + ByteArrayOutputStream outputStream = null; + try { + outputStream = new ByteArrayOutputStream(); + excelWriter = EasyExcel.write(outputStream).build(); + WriteSheet writeSheet = EasyExcel.writerSheet("sheet1").head(QsExcelEntity.class).build(); + excelWriter.write(excelList, writeSheet); + byte[] bytes = outputStream.toByteArray(); + return sendEmailByqs((String) pramsMap.get("emailAddress"),"",bytes); + }catch(Exception e){ + log.error("签收数据导出,错误日志:{}",e); + } finally { + // 千万别忘记finish 会帮忙关闭流 + if (excelWriter != null) { + excelWriter.finish(); + } + if(outputStream != null){ + try { + outputStream.close(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + } + } + JSONObject json = new JSONObject(); + json.put("code", "9999"); + json.put("msg", "邮件发送失败"); + return super.responseResult(json); + } + + //郵件交付 + public String sendEmailByqs(String emailAddress, String ghfsbh, byte[] xlsxFile){ + JSONObject json = new JSONObject(); + //发件方信息 + SendMailVo sendVo = new SendMailVo(); + //发件方邮箱 + sendVo.setSendAddress(baseServiceConfig.getSendAddress()); + //发件方第三方授权码 + sendVo.setAuthPassword(baseServiceConfig.getAuthPassword()); + //发件方名称 + sendVo.setSendName(baseServiceConfig.getSendName()); + //发件方邮件服务器 + sendVo.setSmtpServer(baseServiceConfig.getSmtpServer()); + //邮件服务器端口 + sendVo.setPort(baseServiceConfig.getSslPort()); + + MailContentVo mailContent = new MailContentVo(); + //模板id + mailContent.setTemplateId("50"); + //邮件标题 + mailContent.setSubject(new String[]{"签收结果"}); + //邮件内容 + mailContent.setContent(new String[]{ghfsbh}); + //接收方邮箱 + String[] str = {emailAddress}; + mailContent.setTo(str); + //抄送方邮箱 + mailContent.setCc(new String[]{}); + //附件 excel + List attachmentVoList = Lists.newArrayList(); + AttachmentVo attachmentVo = new AttachmentVo(); + attachmentVo.setName("发票签收"); + attachmentVo.setFileBytes(xlsxFile); + attachmentVo.setType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + mailContent.setAttachmentVos(attachmentVoList); + attachmentVoList.add(attachmentVo); + try { + messageSenderUtil.sendMailExecutor(mailContent,sendVo); + json.put("code", "0"); + json.put("msg", "邮件发送成功"); + } catch (Exception e) { + log.error("邮件发送失败:" + e); + json.put("code", "9999"); + json.put("msg", "邮件发送失败:" + e.getMessage()); + } + return super.responseResult(json); + } + + + // } diff --git a/dxhy-sign/src/main/resources/mapper/SignRecordInvoiceMapper.xml b/dxhy-sign/src/main/resources/mapper/SignRecordInvoiceMapper.xml index 23e54e70..25e6eccf 100644 --- a/dxhy-sign/src/main/resources/mapper/SignRecordInvoiceMapper.xml +++ b/dxhy-sign/src/main/resources/mapper/SignRecordInvoiceMapper.xml @@ -41,6 +41,12 @@ and t.invoice_source = #{invoiceSource} + + and t.id in + + #{item} + + and t.qs_status = '0' and t.source_system='0' and t.invoice_date between #{kprqq} and #{kprqz} From 25d85bc15db3e672685f02fe3b218f0b2ff2045b Mon Sep 17 00:00:00 2001 From: "zhenghaiyang@ele-cloud.com" Date: Mon, 20 Mar 2023 16:04:51 +0800 Subject: [PATCH 4/7] =?UTF-8?q?feature=201.=E9=85=8D=E7=BD=AE=E9=A1=B9?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dxhy-sign/pom.xml | 11 +++++++++++ .../java/com/dxhy/sign/config/BaseServiceConfig.java | 10 +++++----- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/dxhy-sign/pom.xml b/dxhy-sign/pom.xml index 771907ca..fba4170a 100644 --- a/dxhy-sign/pom.xml +++ b/dxhy-sign/pom.xml @@ -13,6 +13,12 @@ ${jxpt.version} jar + + com.dxhy.base + sims-base-sms + 6.1.4.0-BASE + compile + com.dxhy.jxpt dxhy-common @@ -151,6 +157,11 @@ spring-cloud-starter-bootstrap 3.0.2 + + com.alibaba + easyexcel-core + 3.1.1 + ${project.artifactId} diff --git a/dxhy-sign/src/main/java/com/dxhy/sign/config/BaseServiceConfig.java b/dxhy-sign/src/main/java/com/dxhy/sign/config/BaseServiceConfig.java index 5ae63a07..4dc0c818 100644 --- a/dxhy-sign/src/main/java/com/dxhy/sign/config/BaseServiceConfig.java +++ b/dxhy-sign/src/main/java/com/dxhy/sign/config/BaseServiceConfig.java @@ -12,29 +12,29 @@ public class BaseServiceConfig { /** * 客户自定义邮件配置-发件人邮箱地址 */ - @Value("${order.email.customer.sendAddress:}") + @Value("${email.customer.sendAddress:}") private String sendAddress; /** * 客户自定义邮件配置-第三方支持授权码(126和163以及qq邮箱都需要授权码登录,没有授权码的直接登录网页版邮箱设置里设置) * 如果是其他企业邮箱,直接使用邮箱登录密码 */ - @Value("${order.email.customer.authPassword:}") + @Value("${email.customer.authPassword:}") private String authPassword; /** * 客户自定义邮件配置-发件人名称 */ - @Value("${order.email.customer.sendName:}") + @Value("${email.customer.sendName:}") private String sendName; /** * 客户自定义邮件配置-邮件服务器 */ - @Value("${order.email.customer.smtpServer:}") + @Value("${email.customer.smtpServer:}") private String smtpServer; /** * 客户自定义邮件配置-邮件服务器端口 */ - @Value("${order.email.customer.sslPort:}") + @Value("${email.customer.sslPort:}") private String sslPort; From 3ab4cc480a362ae14e4f053ff4f91fa613b50d7e Mon Sep 17 00:00:00 2001 From: "zhenghaiyang@ele-cloud.com" Date: Wed, 22 Mar 2023 08:19:04 +0800 Subject: [PATCH 5/7] =?UTF-8?q?feature=201.=E5=A2=9E=E5=8A=A0OCR=E8=AF=86?= =?UTF-8?q?=E5=88=AB=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/OpenServicePlatformController.java | 11 +++++++++++ .../openservice/IOpenServicePlatformService.java | 1 + .../impl/OpenServicePlatformServiceImpl.java | 5 +++++ 3 files changed, 17 insertions(+) diff --git a/dxhy-core/src/main/java/com/dxhy/core/controller/OpenServicePlatformController.java b/dxhy-core/src/main/java/com/dxhy/core/controller/OpenServicePlatformController.java index 7df80e53..93e500ed 100644 --- a/dxhy-core/src/main/java/com/dxhy/core/controller/OpenServicePlatformController.java +++ b/dxhy-core/src/main/java/com/dxhy/core/controller/OpenServicePlatformController.java @@ -45,4 +45,15 @@ public class OpenServicePlatformController { } } + + @PostMapping("/getInvoiceSnOcrResult") + public List getInvoiceSnOcrResult(@RequestBody Map params) { + try { + String picture = params.get("picture"); + return openServicePlatformService.ocrInvoice(picture); + } catch (Exception e) { + log.error("调用开放平台OCR接口失败,", e); + return null; + } + } } diff --git a/dxhy-core/src/main/java/com/dxhy/core/service/openservice/IOpenServicePlatformService.java b/dxhy-core/src/main/java/com/dxhy/core/service/openservice/IOpenServicePlatformService.java index 7b63feb2..b594817d 100644 --- a/dxhy-core/src/main/java/com/dxhy/core/service/openservice/IOpenServicePlatformService.java +++ b/dxhy-core/src/main/java/com/dxhy/core/service/openservice/IOpenServicePlatformService.java @@ -35,4 +35,5 @@ public interface IOpenServicePlatformService { List getCustomsOcrResult(String uuid, String picture) throws OpenServiceInvokeException; List ocrInvoice(String picture, String userName, String password, String taxno); + List ocrInvoice(String picture); } diff --git a/dxhy-core/src/main/java/com/dxhy/core/service/openservice/impl/OpenServicePlatformServiceImpl.java b/dxhy-core/src/main/java/com/dxhy/core/service/openservice/impl/OpenServicePlatformServiceImpl.java index e64e1122..9cba6c39 100644 --- a/dxhy-core/src/main/java/com/dxhy/core/service/openservice/impl/OpenServicePlatformServiceImpl.java +++ b/dxhy-core/src/main/java/com/dxhy/core/service/openservice/impl/OpenServicePlatformServiceImpl.java @@ -195,6 +195,11 @@ public class OpenServicePlatformServiceImpl implements IOpenServicePlatformServi // return JSONObject.parseArray(decodeStr, OpenServiceOcr.class); } + + @Override + public List ocrInvoice(String picture) { + return OcrToSn(picture); + } /** * Ocr识别使用山能 * @param picture 文件流 From 9fb53c0dcfb556edf2374dd95da490d4c9ae2077 Mon Sep 17 00:00:00 2001 From: "zhenghaiyang@ele-cloud.com" Date: Wed, 22 Mar 2023 14:10:56 +0800 Subject: [PATCH 6/7] =?UTF-8?q?feature=201.=E5=A2=9E=E5=8A=A0=E9=82=AE?= =?UTF-8?q?=E7=AE=B1=E7=AD=BE=E6=94=B6=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sign/controller/SignFpqsController.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/dxhy-sign/src/main/java/com/dxhy/sign/controller/SignFpqsController.java b/dxhy-sign/src/main/java/com/dxhy/sign/controller/SignFpqsController.java index a9753ce7..472f3068 100644 --- a/dxhy-sign/src/main/java/com/dxhy/sign/controller/SignFpqsController.java +++ b/dxhy-sign/src/main/java/com/dxhy/sign/controller/SignFpqsController.java @@ -122,6 +122,29 @@ public class SignFpqsController extends AbstractController { } } + + /** + * 手工签收发票列表查询 + * + * @param pramsMap + * 购方税号,全部时传0 + * + * @return 返回结果 + * + */ + @RequestMapping("/sgqs/sendEmailByQs") + @ResponseBody + @SysLog("手工签收--邮箱签收") + public ResponseEntity sendEmailByQs(@RequestBody Map pramsMap) { + if (pramsMap.get("emailAddress") != null && !"".equals(pramsMap.get("emailAddress"))) { + return ResponseEntity.ok(R.error("邮箱地址不能为空!")); + } + if (pramsMap.get("ids") != null && !"".equals(pramsMap.get("ids"))) { + return ResponseEntity.ok(R.error("未勾选数据!")); + } + return ResponseEntity.ok(signFpqsService.qsSendEmail(pramsMap)); + } + @RequestMapping("/qsExport") public void qsExport(@RequestBody Map pramsMap, HttpServletResponse response){ List excelList = signFpqsService.selectWqsfp(pramsMap); @@ -1127,6 +1150,7 @@ public class SignFpqsController extends AbstractController { } } + /** * 强制签收 * From e6731fe4d855604ec8e7c93c45777f0d08e5f0e9 Mon Sep 17 00:00:00 2001 From: "zhenghaiyang@ele-cloud.com" Date: Wed, 22 Mar 2023 16:31:06 +0800 Subject: [PATCH 7/7] =?UTF-8?q?feature=201.=E6=96=B0=E5=A2=9E=E9=82=AE?= =?UTF-8?q?=E7=AE=B1=E9=87=87=E9=9B=86=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dxhy-core/pom.xml | 10 + .../com/dxhy/core/task/SnEmailGatherTask.java | 120 +++++++ .../com/dxhy/core/util/EmailParseUtils.java | 313 ++++++++++++++++++ 3 files changed, 443 insertions(+) create mode 100644 dxhy-core/src/main/java/com/dxhy/core/task/SnEmailGatherTask.java create mode 100644 dxhy-core/src/main/java/com/dxhy/core/util/EmailParseUtils.java diff --git a/dxhy-core/pom.xml b/dxhy-core/pom.xml index 82b7580a..2562a47a 100644 --- a/dxhy-core/pom.xml +++ b/dxhy-core/pom.xml @@ -13,6 +13,16 @@ ${jxpt.version} jar + + javax.mail + javax.mail-api + 1.6.2 + + + com.sun.mail + javax.mail + 1.6.2 + com.dxhy.jxpt dxhy-common diff --git a/dxhy-core/src/main/java/com/dxhy/core/task/SnEmailGatherTask.java b/dxhy-core/src/main/java/com/dxhy/core/task/SnEmailGatherTask.java new file mode 100644 index 00000000..78653b5f --- /dev/null +++ b/dxhy-core/src/main/java/com/dxhy/core/task/SnEmailGatherTask.java @@ -0,0 +1,120 @@ +package com.dxhy.core.task; + + +import com.dxhy.core.job.service.ScheduleJobService; +import com.dxhy.core.util.EmailParseUtils; +import com.sun.mail.pop3.POP3Folder; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import javax.mail.*; +import javax.mail.internet.MimeMessage; +import java.util.Date; +import java.util.Properties; + + +@Component("snEmailGatherTask") +@Slf4j +public class SnEmailGatherTask { + + @Resource + private ScheduleJobService scheduleJobService; + + + public void mailGatherTask(){ + //进行邮件采集 + + + } + + + + @SneakyThrows + public static void main(String[] args) { + + //邮件接收协议 + String mail_protocol = "mail.store.protocol"; + //邮件接收协议类型 + String mail_protocol_type2 = "pop3"; + String mail_protocol_type = "pop"; + + //邮件接收服务器端口 + String mail_port = "mail.pop3.port"; + //邮件接收服务器端口 + String port = "110"; + //邮件接收服务器地址 + String mail_host = "mail.pop3.host"; + String emailName = "1149953701@qq.com"; + String password = "pmdzleyabmlzgdhc"; + + String mailSuffix = emailName.split("@")[1]; + //邮箱类型 + String mailType = mailSuffix.split("\\.")[0]; + Properties props = new Properties(); + if(mailType.equalsIgnoreCase("qq")){ + //qq邮箱 + props.setProperty(mail_protocol, mail_protocol_type2); // 协议 + props.setProperty(mail_host, mail_protocol_type+"."+mailSuffix); // pop3服务器 + props.setProperty(mail_port, port); // 端口 + }else { + props.setProperty(mail_protocol, mail_protocol_type2); // 协议 + props.setProperty(mail_host, mail_protocol_type2+"."+mailSuffix); // pop3服务器 + props.setProperty(mail_port, port); // 端口 + } + Session session = Session.getInstance(props); + Store store = session.getStore("pop3"); + + //连接邮箱服务器 + store.connect(emailName, password); + //获取当前时间 + Date currentTime = new Date(); + // 获得收件箱 pop3协议只有一个有效的文件夹就是INBOX + Folder folder = store.getFolder("INBOX"); + //获取邮件列表 + folder.open(Folder.READ_WRITE); + + // 由于POP3协议无法获知邮件的状态,所以getUnreadMessageCount得到的是收件箱的邮件总数 + System.out.println("未读邮件数: " + folder.getUnreadMessageCount()); + + // 由于POP3协议无法获知邮件的状态,所以下面得到的结果始终都是为0 + System.out.println("删除邮件数: " + folder.getDeletedMessageCount()); + System.out.println("新邮件: " + folder.getNewMessageCount()); + + // 获得收件箱中的邮件总数 + System.out.println("邮件总数: " + folder.getMessageCount()); + + Message[] messages = folder.getMessages(); + for (int i = 0, count = messages.length; i < count; i++) { + MimeMessage msg = (MimeMessage) messages[i]; + System.out.println("------------------解析第" + msg.getMessageNumber() + "封邮件-------------------- "); + System.out.println("主题: " + EmailParseUtils.getSubject(msg)); + System.out.println("发件人: " + EmailParseUtils.getFrom(msg)); + System.out.println("收件人:" + EmailParseUtils.getReceiveAddress(msg, null)); + System.out.println("发送时间:" + EmailParseUtils.getSentDate(msg, null)); + System.out.println("是否已读:" + EmailParseUtils.isSeen(msg)); + System.out.println("邮件优先级:" + EmailParseUtils.getPriority(msg)); + System.out.println("是否需要回执:" + EmailParseUtils.isReplySign(msg)); + System.out.println("邮件大小:" + msg.getSize() * 1024 + "kb"); + boolean isContainerAttachment = EmailParseUtils.isContainAttachment(msg); + POP3Folder inbox = (POP3Folder) folder; + String uid = inbox.getUID(msg); + System.out.println("uid: ------------------" + uid); + Flags flags = msg.getFlags(); + if (!flags.contains(Flags.Flag.SEEN)) { + //设置为已读 + msg.setFlag(Flags.Flag.SEEN, true); + } + System.out.println(""); + } + System.out.println(""); + + Date endTime = new Date(); + //计算耗时时间 +// double elapsedTime = CalendarUtil.arithDateTime(endTime, currentTime); + // 释放资源 + folder.close(false); // false为不更新邮件,true为更新,一般在删除邮件后使用 + store.close(); + } +} diff --git a/dxhy-core/src/main/java/com/dxhy/core/util/EmailParseUtils.java b/dxhy-core/src/main/java/com/dxhy/core/util/EmailParseUtils.java new file mode 100644 index 00000000..2028594c --- /dev/null +++ b/dxhy-core/src/main/java/com/dxhy/core/util/EmailParseUtils.java @@ -0,0 +1,313 @@ +package com.dxhy.core.util; + +import javax.mail.*; +import javax.mail.internet.InternetAddress; +import javax.mail.internet.MimeMessage; +import javax.mail.internet.MimeMultipart; +import javax.mail.internet.MimeUtility; +import java.io.*; +import java.text.SimpleDateFormat; +import java.util.Date; + +public class EmailParseUtils { + + /** + * 解析邮件 + * + * @param messages 要解析的邮件列表 + */ + public static void deleteMessage(Message... messages) throws MessagingException, IOException { + if (messages == null || messages.length < 1) + throw new MessagingException("未找到要解析的邮件!"); + + // 解析所有邮件 + for (int i = 0, count = messages.length; i < count; i++) { + + /** + * 邮件删除 + */ + Message message = messages[i]; + String subject = message.getSubject(); + // set the DELETE flag to true + message.setFlag(Flags.Flag.DELETED, true); + System.out.println("Marked DELETE for message: " + subject); + + + } + } + + /** + * 获得邮件主题 + * + * @param msg 邮件内容 + * @return 解码后的邮件主题 + */ + public static String getSubject(MimeMessage msg) throws UnsupportedEncodingException, MessagingException { + return MimeUtility.decodeText(msg.getSubject()); + } + + /** + * 获得邮件发件人 + * + * @param msg 邮件内容 + * @return 姓名 + * @throws MessagingException + * @throws UnsupportedEncodingException + */ + public static String getFrom(MimeMessage msg) throws MessagingException, UnsupportedEncodingException { + String from = ""; + Address[] froms = msg.getFrom(); + if (froms.length < 1) + throw new MessagingException("没有发件人!"); + + InternetAddress address = (InternetAddress) froms[0]; + String person = address.getPersonal(); + if (person != null) { + person = MimeUtility.decodeText(person) + " "; + } else { + person = ""; + } + from = person + "<" + address.getAddress() + ">"; + + return from; + } + + /** + * 根据收件人类型,获取邮件收件人、抄送和密送地址。如果收件人类型为空,则获得所有的收件人 + *

Message.RecipientType.TO 收件人

+ *

Message.RecipientType.CC 抄送

+ *

Message.RecipientType.BCC 密送

+ * + * @param msg 邮件内容 + * @param type 收件人类型 + * @return 收件人1 <邮件地址1>, 收件人2 <邮件地址2>, ... + * @throws MessagingException + */ + public static String getReceiveAddress(MimeMessage msg, Message.RecipientType type) throws MessagingException { + StringBuffer receiveAddress = new StringBuffer(); + Address[] addresss = null; + if (type == null) { + addresss = msg.getAllRecipients(); + } else { + addresss = msg.getRecipients(type); + } + + if (addresss == null || addresss.length < 1) + throw new MessagingException("没有收件人!"); + for (Address address : addresss) { + InternetAddress internetAddress = (InternetAddress) address; + receiveAddress.append(internetAddress.toUnicodeString()).append(","); + } + + receiveAddress.deleteCharAt(receiveAddress.length() - 1); //删除最后一个逗号 + + return receiveAddress.toString(); + } + + /** + * 获得邮件发送时间 + * + * @param msg 邮件内容 + * @return yyyy年mm月dd日 星期X HH:mm + * @throws MessagingException + */ + public static String getSentDate(MimeMessage msg, String pattern) throws MessagingException { + Date receivedDate = msg.getSentDate(); + if (receivedDate == null) + return ""; + + if (pattern == null || "".equals(pattern)) + pattern = "yyyy年MM月dd日 E HH:mm "; + + return new SimpleDateFormat(pattern).format(receivedDate); + } + + /** + * 判断邮件中是否包含附件 + *

+ * //* @param msg 邮件内容 + * + * @return 邮件中存在附件返回true,不存在返回false + * @throws MessagingException + * @throws IOException + */ + public static boolean isContainAttachment(Part part) throws MessagingException, IOException { + boolean flag = false; + if (part.isMimeType("multipart/*")) { + MimeMultipart multipart = (MimeMultipart) part.getContent(); + int partCount = multipart.getCount(); + for (int i = 0; i < partCount; i++) { + BodyPart bodyPart = multipart.getBodyPart(i); + String disp = bodyPart.getDisposition(); + if (disp != null && (disp.equalsIgnoreCase(Part.ATTACHMENT) || disp.equalsIgnoreCase(Part.INLINE))) { + flag = true; + } else if (bodyPart.isMimeType("multipart/*")) { + flag = isContainAttachment(bodyPart); + } else { + String contentType = bodyPart.getContentType(); + if (contentType.indexOf("application") != -1) { + flag = true; + } + + if (contentType.indexOf("name") != -1) { + flag = true; + } + } + + if (flag) break; + } + } else if (part.isMimeType("message/rfc822")) { + flag = isContainAttachment((Part) part.getContent()); + } + return flag; + } + + /** + * 判断邮件是否已读 + * + * @param msg 邮件内容 + * @return 如果邮件已读返回true, 否则返回false + * @throws MessagingException + */ + public static boolean isSeen(MimeMessage msg) throws MessagingException { + return msg.getFlags().contains(Flags.Flag.SEEN); + } + + /** + * 判断邮件是否需要阅读回执 + * + * @param msg 邮件内容 + * @return 需要回执返回true, 否则返回false + * @throws MessagingException + */ + public static boolean isReplySign(MimeMessage msg) throws MessagingException { + boolean replySign = false; + String[] headers = msg.getHeader("Disposition-Notification-To"); + if (headers != null) + replySign = true; + return replySign; + } + + /** + * 获得邮件的优先级 + * + * @param msg 邮件内容 + * @return 1(High):紧急 3:普通(Normal) 5:低(Low) + * @throws MessagingException + */ + public static String getPriority(MimeMessage msg) throws MessagingException { + String priority = "普通"; + String[] headers = msg.getHeader("X-Priority"); + if (headers != null) { + String headerPriority = headers[0]; + if (headerPriority.indexOf("1") != -1 || headerPriority.indexOf("High") != -1) + priority = "紧急"; + else if (headerPriority.indexOf("5") != -1 || headerPriority.indexOf("Low") != -1) + priority = "低"; + else + priority = "普通"; + } + return priority; + } + + /** + * 获得邮件文本内容 + * + * @param part 邮件体 + * @param content 存储邮件文本内容的字符串 + * @throws MessagingException + * @throws IOException + */ + public static void getMailTextContent(Part part, StringBuffer content) throws MessagingException, IOException { + //如果是文本类型的附件,通过getContent方法可以取到文本内容,但这不是我们需要的结果,所以在这里要做判断 + boolean isContainTextAttach = part.getContentType().indexOf("name") > 0; + if (part.isMimeType("text/*") && !isContainTextAttach) { + content.append(part.getContent().toString()); + } else if (part.isMimeType("message/rfc822")) { + getMailTextContent((Part) part.getContent(), content); + } else if (part.isMimeType("multipart/*")) { + Multipart multipart = (Multipart) part.getContent(); + int partCount = multipart.getCount(); + for (int i = 0; i < partCount; i++) { + BodyPart bodyPart = multipart.getBodyPart(i); + getMailTextContent(bodyPart, content); + } + } + } + + /** + * 保存附件 + * + * @param part 邮件中多个组合体中的其中一个组合体 + * @param destDir 附件保存目录 + * @throws UnsupportedEncodingException + * @throws MessagingException + * @throws FileNotFoundException + * @throws IOException + */ + public static void saveAttachment(Part part, String destDir) throws UnsupportedEncodingException, MessagingException, + FileNotFoundException, IOException { + if (part.isMimeType("multipart/*")) { + Multipart multipart = (Multipart) part.getContent(); //复杂体邮件 + //复杂体邮件包含多个邮件体 + int partCount = multipart.getCount(); + for (int i = 0; i < partCount; i++) { + //获得复杂体邮件中其中一个邮件体 + BodyPart bodyPart = multipart.getBodyPart(i); + //某一个邮件体也有可能是由多个邮件体组成的复杂体 + String disp = bodyPart.getDisposition(); + if (disp != null && (disp.equalsIgnoreCase(Part.ATTACHMENT) || disp.equalsIgnoreCase(Part.INLINE))) { + InputStream is = bodyPart.getInputStream(); + saveFile(is, destDir, decodeText(bodyPart.getFileName())); + } else if (bodyPart.isMimeType("multipart/*")) { + saveAttachment(bodyPart, destDir); + } else { + String contentType = bodyPart.getContentType(); + if (contentType.indexOf("name") != -1 || contentType.indexOf("application") != -1) { + saveFile(bodyPart.getInputStream(), destDir, decodeText(bodyPart.getFileName())); + } + } + } + } else if (part.isMimeType("message/rfc822")) { + saveAttachment((Part) part.getContent(), destDir); + } + } + + /** + * 读取输入流中的数据保存至指定目录 + * + * @param is 输入流 + * @param fileName 文件名 + * @param destDir 文件存储目录 + * @throws FileNotFoundException + * @throws IOException + */ + private static void saveFile(InputStream is, String destDir, String fileName) + throws FileNotFoundException, IOException { + BufferedInputStream bis = new BufferedInputStream(is); + BufferedOutputStream bos = new BufferedOutputStream( + new FileOutputStream(new File(destDir + fileName))); + int len = -1; + while ((len = bis.read()) != -1) { + bos.write(len); + bos.flush(); + } + bos.close(); + bis.close(); + } + + /** + * 文本解码 + * + * @param encodeText 解码MimeUtility.encodeText(String text)方法编码后的文本 + * @return 解码后的文本 + * @throws UnsupportedEncodingException + */ + public static String decodeText(String encodeText) throws UnsupportedEncodingException { + if (encodeText == null || "".equals(encodeText)) { + return ""; + } else { + return MimeUtility.decodeText(encodeText); + } + } +}