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 aad66723..7520bf74 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,17 +1,15 @@ 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; +import java.io.*; + /** * @author jiaohongyang */ @@ -172,10 +170,10 @@ public class FileUtil { } //新增文件上传接口 - public static String uploadFile(String url, String fileStream) { + public static String uploadFile(String url, byte[] bytes) { HttpPost httpPost = new HttpPost(url); MultipartEntityBuilder builder = MultipartEntityBuilder.create(); - builder.addBinaryBody("file",fileStream.getBytes(Charset.forName("UTF-8"))); + builder.addBinaryBody("file", bytes); HttpEntity multipart = builder.build(); httpPost.setEntity(multipart); String result = ""; diff --git a/dxhy-core/src/main/java/com/dxhy/core/model/mailGather/EmailMaintainVo.java b/dxhy-core/src/main/java/com/dxhy/core/model/mailGather/EmailMaintainVo.java index b3c973d8..61718d5b 100644 --- a/dxhy-core/src/main/java/com/dxhy/core/model/mailGather/EmailMaintainVo.java +++ b/dxhy-core/src/main/java/com/dxhy/core/model/mailGather/EmailMaintainVo.java @@ -15,11 +15,14 @@ public class EmailMaintainVo extends CommonDTO { public String deptId; + private String companyCode; + public String deptName; public String username; public String userId; + public String emailAddress; public String emailPassword; public String delStatus; diff --git a/dxhy-core/src/main/java/com/dxhy/core/model/mailGather/OcrResultToyxVo.java b/dxhy-core/src/main/java/com/dxhy/core/model/mailGather/OcrResultToyxVo.java new file mode 100644 index 00000000..66f57ae8 --- /dev/null +++ b/dxhy-core/src/main/java/com/dxhy/core/model/mailGather/OcrResultToyxVo.java @@ -0,0 +1,44 @@ +package com.dxhy.core.model.mailGather; + +import lombok.Data; + +@Data +public class OcrResultToyxVo { + + //序号 + private String ZNO; + //公司代码 + private String ZBUKRS; + //提交人账号 + private String ZUSER; + //文件名 + private String ZNAME; + //文件内容(非结构化数据) + private String ZCONTENT; + //文件上传日期 + private String ZFILEDATE; + //是否为发票 + private String ZFLAG; + //发票号码 + private String ZFPHM; + //发票代码 + private String ZFPDM; + //发票类型 + private String ZFPLX; + //发票日期 + private String ZKPRQ; + //发票含税金额 + private String ZHSJE; + //发票购方名称 + private String ZGFMC; + //发票销方名称 + private String ZXFMC; + //发票图片内容(非结构化数据) + private String ZFPFILE; + //发票图片URL + private String ZFPURL; + //来源邮箱地址 + private String ZFMAIL; + //数据来源系统 + private String ZLYXT; +} diff --git a/dxhy-core/src/main/java/com/dxhy/core/model/openservice/OpenServiceOcr.java b/dxhy-core/src/main/java/com/dxhy/core/model/openservice/OpenServiceOcr.java index f700247e..9560d64d 100644 --- a/dxhy-core/src/main/java/com/dxhy/core/model/openservice/OpenServiceOcr.java +++ b/dxhy-core/src/main/java/com/dxhy/core/model/openservice/OpenServiceOcr.java @@ -1,10 +1,10 @@ package com.dxhy.core.model.openservice; +import lombok.Data; + import java.io.Serializable; import java.util.List; -import lombok.Data; - /** * @author user */ @@ -15,6 +15,8 @@ public class OpenServiceOcr implements Serializable { private String FPLXDM; private String XZJD; + // SN + private String IMAGE; private InvoiceOcrData data; diff --git a/dxhy-core/src/main/java/com/dxhy/core/service/mailGather/impl/EmailMaintainServiceImpl.java b/dxhy-core/src/main/java/com/dxhy/core/service/mailGather/impl/EmailMaintainServiceImpl.java index cd59c1c2..cae86c03 100644 --- a/dxhy-core/src/main/java/com/dxhy/core/service/mailGather/impl/EmailMaintainServiceImpl.java +++ b/dxhy-core/src/main/java/com/dxhy/core/service/mailGather/impl/EmailMaintainServiceImpl.java @@ -4,6 +4,8 @@ package com.dxhy.core.service.mailGather.impl; import cn.hutool.core.codec.Base64; import cn.hutool.core.util.IdUtil; import com.alibaba.fastjson.JSONObject; +import com.dxhy.common.constant.DbConstant; +import com.dxhy.common.datasource.config.DynamicContextHolder; import com.dxhy.core.dao.mailGather.EmailMaintainDao; import com.dxhy.core.model.mailGather.EmailMaintainVo; import com.dxhy.core.service.mailGather.EmailMaintainService; @@ -105,4 +107,10 @@ public class EmailMaintainServiceImpl implements EmailMaintainService { public boolean deleteById(String id) { return this.emailMaintainDao.deleteById(id) > 0; } + + //根据用户名进行查询 + public void getdeptInfo(String deptId){ + DynamicContextHolder.push(DbConstant.BASICS_READ); + + } } 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 9cba6c39..9089d0ae 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,32 +1,28 @@ package com.dxhy.core.service.openservice.impl; -import java.io.*; -import java.util.*; -import java.util.stream.Collectors; - -import javax.annotation.Resource; - +import cn.hutool.core.codec.Base64; 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; - +import cn.hutool.http.HttpUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.TypeReference; +import com.dxhy.common.util.FileUtil; import com.dxhy.core.job.service.impl.MakeAppSecService; import com.dxhy.core.model.openservice.*; import com.dxhy.core.service.openservice.IOpenServicePlatformService; - -import cn.hutool.core.codec.Base64; -import cn.hutool.core.date.DatePattern; -import cn.hutool.core.date.DateUtil; -import cn.hutool.http.HttpUtil; +import com.dxhy.core.service.openservice.model.ocr.*; +import com.google.common.collect.Lists; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; +import java.util.stream.Collectors; /** * @author user @@ -209,7 +205,7 @@ public class OpenServicePlatformServiceImpl implements IOpenServicePlatformServi //判断是否为图片流文件, 兼容公司平台进行base64解密 String str = Base64Decoder.decodeStr(picture); String requestUrl = snOcrUrl; - String result = FileUtil.uploadFile(requestUrl, str); + String result = FileUtil.uploadFile(requestUrl, Base64Decoder.decode(picture)); if(StringUtils.isBlank(result)){ log.info("调用山能ocr识别失败"); }else { @@ -222,19 +218,44 @@ public class OpenServicePlatformServiceImpl implements IOpenServicePlatformServi return null; } + /** + * Ocr识别使用山能 + * @param picture 文件流 + * @return + */ + public static List OcrToSnTest(String picture){ + //判断是否为图片流文件, 兼容公司平台进行base64解密 + String str = Base64Decoder.decodeStr(picture); + String requestUrl = "http://192.168.33.102:30006/cci_ai/service/v1/receipt_crop_and_recog?crop_complete_image=1"; + String result = FileUtil.uploadFile(requestUrl, Base64Decoder.decode(picture)); + 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){ + public static List dxOcrConvertSnOcr(List ocrDataListEntities){ List openServices = Lists.newArrayList(); for (OcrDataListEntity ocrDataListEntity : ocrDataListEntities) { - OpenServiceOcr serviceOcr = new OpenServiceOcr(); List> productList = ocrDataListEntity.getProductList(); List itemList = ocrDataListEntity.getItemList(); + String type = ocrDataListEntity.getType(); + if("other".equals(type)){ + break; + } + Map itemData = itemList.stream().collect(Collectors.toMap(OcrItemListEntity::getKey, OcrItemListEntity::getValue)); OpenServiceOcr openServiceOcr = new OpenServiceOcr(); - - String type = ocrDataListEntity.getType(); + openServiceOcr.setIMAGE(ocrDataListEntity.getImage()); //type 为 vat_special_invoice(增值税专用发票)、vat_electronic_invoice(增 //值税电子普通发票)、vat_common_invoice(增值税普通发票)、 //vat_electronic_toll_invoice(增值税电子普通发票(通行费)) @@ -249,9 +270,8 @@ public class OpenServicePlatformServiceImpl implements IOpenServicePlatformServi //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.setFPLXDM(OcrDataTypeEnum.getVal(type)); // openServiceOcr.setXZJD(itemData.get(OcrDataTypeEnum.VAT_INVOICE_TYPE.getKey())); - OpenServiceOcr.InvoiceOcrData invoiceOcrData = new OpenServiceOcr.InvoiceOcrData(); invoiceOcrData.setSFCY("0"); //是否查验 //判断发票类型 @@ -291,20 +311,21 @@ public class OpenServicePlatformServiceImpl implements IOpenServicePlatformServi invoiceOcrData.setSFYGSYZ("False".equals(itemData.get(OcrDataTypeEnum.EXIST_STAMPLE.getKey()))?"0":"1"); List invoiceOcrDetailList = Lists.newArrayList(); - for (List productListEntities : productList) { + for (List productListEntities: productList) { + Map productMap = productListEntities.stream().collect(Collectors.toMap(OcrProductListEntity::getKey, OcrProductListEntity::getValue)); 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())); + invoiceOcrDetail.setHWMC(productMap.get(OcrDataTypeEnum.VAT_INVOICE_GOODS.getKey())); + invoiceOcrDetail.setGGXH(productMap.get(OcrDataTypeEnum.VAT_INVOICE_PLATE_SPECIFIC.getKey())); + invoiceOcrDetail.setDW(productMap.get(OcrDataTypeEnum.VAT_INVOICE_ELECTRANS_UNIT.getKey())); + invoiceOcrDetail.setSPSL(productMap.get(OcrDataTypeEnum.VAT_INVOICE_ELECTRANS_QUANTITY.getKey())); + invoiceOcrDetail.setDJ(productMap.get(OcrDataTypeEnum.VAT_INVOICE_ELECTRANS_UNIT_PRICE.getKey())); + invoiceOcrDetail.setJE(productMap.get(OcrDataTypeEnum.VAT_INVOICE_PRICE.getKey())); + invoiceOcrDetail.setSL(productMap.get(OcrDataTypeEnum.VAT_INVOICE_TAX_RATE.getKey())); + invoiceOcrDetail.setSE(productMap.get(OcrDataTypeEnum.VAT_INVOICE_TAX.getKey())); invoiceOcrDetailList.add(invoiceOcrDetail); - invoiceOcrData.setFPMX(invoiceOcrDetailList); } + 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())); @@ -323,19 +344,20 @@ public class OpenServicePlatformServiceImpl implements IOpenServicePlatformServi List invoiceOcrDetailList = Lists.newArrayList(); for (List productListEntities : productList) { + Map productMap = productListEntities.stream().collect(Collectors.toMap(OcrProductListEntity::getKey, OcrProductListEntity::getValue)); 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())); + invoiceOcrDetail.setHWMC(productMap.get(OcrDataTypeEnum.VAT_INVOICE_GOODS.getKey())); + invoiceOcrDetail.setGGXH(productMap.get(OcrDataTypeEnum.VAT_INVOICE_PLATE_SPECIFIC.getKey())); + invoiceOcrDetail.setDW(productMap.get(OcrDataTypeEnum.VAT_INVOICE_ELECTRANS_UNIT.getKey())); + invoiceOcrDetail.setSPSL(productMap.get(OcrDataTypeEnum.VAT_INVOICE_ELECTRANS_QUANTITY.getKey())); + invoiceOcrDetail.setDJ(productMap.get(OcrDataTypeEnum.VAT_INVOICE_ELECTRANS_UNIT_PRICE.getKey())); + invoiceOcrDetail.setJE(productMap.get(OcrDataTypeEnum.VAT_INVOICE_PRICE.getKey())); + invoiceOcrDetail.setSL(productMap.get(OcrDataTypeEnum.VAT_INVOICE_TAX_RATE.getKey())); + invoiceOcrDetail.setSE(productMap.get(OcrDataTypeEnum.VAT_INVOICE_TAX.getKey())); invoiceOcrDetailList.add(invoiceOcrDetail); - invoiceOcrData.setFPMX(invoiceOcrDetailList); } + invoiceOcrData.setFPMX(invoiceOcrDetailList); } else if ("motor_vehicle_sale_invoice".equals(type)) { // -------------机动车销售统一发票特殊字段-------------- invoiceOcrData.setGMFMC(itemData.get(OcrDataTypeEnum.VEHICLE_INVOICE_BUYER.getKey())); @@ -431,7 +453,7 @@ public class OpenServicePlatformServiceImpl implements IOpenServicePlatformServi invoiceOcrData.setJSHJ(itemData.get(OcrDataTypeEnum.MONEY.getKey())); invoiceOcrData.setFPHM(itemData.get(OcrDataTypeEnum.INVOICE_NUMBER.getKey())); } - + openServiceOcr.setData(invoiceOcrData); openServiceOcr.setRegion(ocrDataListEntity.getPosition()); openServices.add(openServiceOcr); } 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 index 1ca4a7af..9a5cfbe1 100644 --- 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 @@ -176,12 +176,55 @@ public enum OcrDataTypeEnum { // invoice_code ("invoice_code","发票代码"), // invoice_number ("invoice_number","发票号码"), - MONEY ("money","金额"), + MONEY ("money","金额"), // date ("date","日期"), - TIME ("time","时间"), + TIME ("time","时间"), TOLL_CODE ("toll_code","车辆通行费代码"), TOLL_NUMBER ("toll_number","车辆通行费号码"), + //增值税专用发票 + VAT_SPECIAL_INVOICE("vat_special_invoice","01"), + //机动车销售统一发票 + MOTOR_VEHICLE_SALE_INVOICE("motor_vehicle_sale_invoice","03"), +// vat_transport_invoice("vat_transport_invoice","货物运输业增值税专用发票"), + //增值税普通发票 + VAT_TRANSPORT_INVOICE("vat_transport_invoice","04"), + //增值税电子普通发票 + VAT_ELECTRONIC_INVOICE("vat_electronic_invoice","10"), +// vat_electronic_invoice("vat_electronic_invoice 区块链发票(需要结合 vat_invoice_zhuan_yong_flag字段综合判断"), + //增值税普通发票(卷票) + VAT_ROLL_INVOICE("vat_roll_invoice","11"), + //增值税电子普通发票(通行费) + VAT_ELECTRONIC_TOLL_INVOICE("vat_electronic_toll_invoice","14"), + //二手车销售统一发票 + USED_CAR_PURCHASE_INVOICE("used_car_purchase_invoice","15"), + //通用机打发票 + GENERAL_MACHINE_INVOICE("general_machine_invoice","97"), + //通用定额发票 + QUOTA_INVOICE("quota_invoice","95"), + PASSENGER_TRANSPORT_INVOICE("PASSENGER_TRANSPORT_INVOICE","旅客运输普票"), + //公路客运发票 + HIGHWAY_PASSENGER_INVOICE("highway_passenger_invoice","94"), + //船运客票 + SHIPPING_INVOICE("shipping_invoice","88"), + //出租车发票 + TAXI_TICKET("taxi_ticket","91"), + + PARKING_INVOICE("highway_passenger_invoice","停车费发票"), + //过路过桥费发票、汽车通行费 + VEHICLE_TOLL("vehicle_toll","98"), + +// MEDICAL_RECEIPT("highway_passenger_invoice","医疗费收据"), +// +// EDUCATION_RECEIPT("highway_passenger_invoice","教育费收据"), + //行程单 + AIR_TRANSPORT("air_transport","93"), + //火车票 + TRAIN_TICKET("train_ticket","94"), + //其它类型 + OTHER("other","00"), + + // invoice_number ("invoice_number","发票号码"), // money ("money","金额"), @@ -191,7 +234,21 @@ public enum OcrDataTypeEnum { private String value; + public String getValue() { + return value; + } + public String getKey() { return key; } + + + public static String getVal(String key) { + for (OcrDataTypeEnum ocrDataType : OcrDataTypeEnum.values()) { + if (ocrDataType.key.equals(key)) { + return ocrDataType.getValue(); + } + } + return null; + } } 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 index 3d6912f1..cecdaf06 100644 --- a/dxhy-core/src/main/java/com/dxhy/core/task/SnEmailGatherTask.java +++ b/dxhy-core/src/main/java/com/dxhy/core/task/SnEmailGatherTask.java @@ -9,12 +9,11 @@ import com.dxhy.core.job.entity.ScheduleJobEntity; import com.dxhy.core.job.service.ScheduleJobService; import com.dxhy.core.model.mailGather.EmailMaintainVo; import com.dxhy.core.model.mailGather.MailGatherLogVo; -import com.dxhy.core.model.openservice.OpenServiceOcr; import com.dxhy.core.service.mailGather.EmailMaintainService; import com.dxhy.core.service.mailGather.MailGatherLogService; import com.dxhy.core.service.openservice.IOpenServicePlatformService; import com.dxhy.core.util.EmailParseUtils; -import com.google.common.collect.Maps; +import com.google.common.collect.Lists; import com.sun.mail.pop3.POP3Folder; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; @@ -59,11 +58,11 @@ public class SnEmailGatherTask { //挨个邮箱进行数据采集 parseEmail(maintainVo); } - log.info("发票获取接口执行结束--"); + log.info("邮箱采集接口执行结束--"); } catch (Exception e) { e.printStackTrace(); } finally { - log.info("发票获取接口--重置执行状态"); + log.info("邮箱采集--重置执行状态"); scheduleJobEntity.setJobStatus("0"); DynamicContextHolder.push(DbConstant.BASICS_WRITE); scheduleJobService.updateById(scheduleJobEntity); @@ -87,6 +86,7 @@ public class SnEmailGatherTask { gatherLogVo.setCreateTime(new Date()); gatherLogVo.setFromAddress(emailName); mailGatherLogService.insert(gatherLogVo); + return; } Folder folder = store.getFolder("INBOX"); //获取邮件列表 @@ -105,7 +105,6 @@ public class SnEmailGatherTask { MimeMessage msg = (MimeMessage) messages[i]; log.debug("------------------解析第" + msg.getMessageNumber() + "封邮件-------------------- "); - MailGatherLogVo gatherLogVo = new MailGatherLogVo(); gatherLogVo.setId(IdUtil.nanoId()); gatherLogVo.setSubject(EmailParseUtils.getSubject(msg)); @@ -125,7 +124,7 @@ public class SnEmailGatherTask { POP3Folder inbox = (POP3Folder) folder; String uid = inbox.getUID(msg); - if(StringUtils.isBlank(maintainVo.getEmailUid()) && i == 0){ + if(StringUtils.isBlank(maintainVo.getEmailUid()) && i+1 == messages.length){ emailMaintainVo.setEmailUid(uid); } //增量处理 等于之后就跳过本地循环 @@ -135,20 +134,22 @@ public class SnEmailGatherTask { gatherLogVo.setMsgUid(uid); boolean isContainerAttachment = EmailParseUtils.isContainAttachment(msg); if(isContainerAttachment){ - Map map = Maps.newHashMap(); - EmailParseUtils.saveAttachment(msg, map); - - gatherLogVo.setFileType(map.get("contentType")); - gatherLogVo.setFileName(map.get("fileName")); - String pdfStream = map.get("pdfStream"); - List openServiceOcrs = openServicePlatformService.ocrInvoice(pdfStream); - if(openServiceOcrs != null && !openServiceOcrs.isEmpty()){ - openServiceOcrs.get(0).getData().getFPDM(); - gatherLogVo.setFpdm( openServiceOcrs.get(0).getData().getFPDM()); - gatherLogVo.setFphm( openServiceOcrs.get(0).getData().getFPHM()); - } - + List> mapList = Lists.newArrayList(); + EmailParseUtils.saveAttachment(msg, mapList); +// gatherLogVo.setFileType(map.get("contentType")); +// gatherLogVo.setFileName(map.get("fileName")); +// String pdfStream = map.get("pdfStream"); +// if(StringUtils.isNotBlank(pdfStream)){ +// List openServiceOcrs = openServicePlatformService.ocrInvoice(pdfStream); +// if(openServiceOcrs != null && !openServiceOcrs.isEmpty()){ +// openServiceOcrs.get(0).getData().getFPDM(); +// gatherLogVo.setFpdm( openServiceOcrs.get(0).getData().getFPDM()); +// gatherLogVo.setFphm( openServiceOcrs.get(0).getData().getFPHM()); +// } else { +// +// } +// } }else { //无附件的不处理 continue; } @@ -167,8 +168,6 @@ public class SnEmailGatherTask { log.info("未采集到有效数据"); } } - - // 释放资源 folder.close(false); // false为不更新邮件,true为更新,一般在删除邮件后使用 store.close(); @@ -180,7 +179,6 @@ public class SnEmailGatherTask { } } - public Store mailAuth(String emailName, String password){ //判断是否为QQ还是163 //邮件接收协议 @@ -319,6 +317,5 @@ public class SnEmailGatherTask { } catch (IOException e) { throw new RuntimeException(e); } - } } diff --git a/dxhy-core/src/main/java/com/dxhy/core/task/SnEmailGatherTaskTest.java b/dxhy-core/src/main/java/com/dxhy/core/task/SnEmailGatherTaskTest.java new file mode 100644 index 00000000..7c72db13 --- /dev/null +++ b/dxhy-core/src/main/java/com/dxhy/core/task/SnEmailGatherTaskTest.java @@ -0,0 +1,201 @@ +package com.dxhy.core.task; + +import com.dxhy.core.model.mailGather.OcrResultToyxVo; +import com.dxhy.core.model.openservice.OpenServiceOcr; +import com.dxhy.core.service.openservice.impl.OpenServicePlatformServiceImpl; +import com.dxhy.core.util.EmailParseUtils; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.sun.mail.pop3.POP3Folder; +import org.apache.commons.lang3.StringUtils; +import org.joda.time.DateTime; +import org.junit.jupiter.api.Test; + +import javax.mail.*; +import javax.mail.internet.MimeMessage; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.util.*; + +class SnEmailGatherTaskTest { + + @Test + void parseEmail() { + //邮件接收协议 + 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 = "15201210373@163.com"; + String password = "JKZATQTPHDDQTQSH"; + 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 = null; + try { + 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()); + +// Calendar calendar = Calendar.getInstance(); +// // 搜索1天前到今天收到的的所有邮件,根据时间筛选邮件 +// calendar.add(Calendar.DAY_OF_MONTH, -1); +// // 创建ReceivedDateTerm对象,ComparisonTerm.GE(大于等于),Date类型的时间 new Date(calendar.getTimeInMillis())----(表示1天前) +// SentDateTerm term = new SentDateTerm(ComparisonTerm.LE, new Date(calendar.getTimeInMillis())); +// Message[] messages = folder.search(term); + 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); + if(isContainerAttachment) { + List> mapList = Lists.newArrayList(); + EmailParseUtils.saveAttachment(msg, mapList); + for (Map map : mapList) { + map.put("emailName",emailName); + String pdfStream = map.get("pdfStream"); + if(StringUtils.isNotBlank(pdfStream)){ + List openServiceOcrs = OpenServicePlatformServiceImpl.OcrToSnTest(pdfStream); + if(openServiceOcrs != null && !openServiceOcrs.isEmpty()){ + convertToOcrResult(openServiceOcrs,map); + } + } + System.out.println(""); + } + + } + 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(); + } catch (NoSuchProviderException e) { + throw new RuntimeException(e); + } catch (MessagingException e) { + throw new RuntimeException(e); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public static List convertToOcrResult(List openServiceOcrs, Map map){ + List resultToyxVoList = Lists.newArrayList(); + for (int i = 0; i < openServiceOcrs.size(); i++) { + OpenServiceOcr openServiceOcr = openServiceOcrs.get(i); + OpenServiceOcr.InvoiceOcrData invoiceOcrData = openServiceOcr.getData(); + OcrResultToyxVo resultToyxVo = new OcrResultToyxVo(); + resultToyxVo.setZNO(i+1+""); + resultToyxVo.setZBUKRS(""); + resultToyxVo.setZUSER(""); + resultToyxVo.setZNAME(map.get("fileName")); + resultToyxVo.setZCONTENT(openServiceOcr.getIMAGE()); + resultToyxVo.setZFILEDATE(new DateTime().toString()); + if(StringUtils.isNotBlank(invoiceOcrData.getFPHM())){ + resultToyxVo.setZFLAG("X"); + } + resultToyxVo.setZFPHM(invoiceOcrData.getFPHM()); + resultToyxVo.setZFPDM(invoiceOcrData.getFPDM()); + Map invoiceType = convertInvoiceType(); + resultToyxVo.setZFPLX(invoiceType.get("")); + resultToyxVo.setZKPRQ(invoiceOcrData.getKPRQ()); + resultToyxVo.setZHSJE(invoiceOcrData.getJSHJ()); + resultToyxVo.setZGFMC(invoiceOcrData.getGMFMC()); + resultToyxVo.setZXFMC(invoiceOcrData.getXHFMC()); + resultToyxVo.setZFPFILE(""); + resultToyxVo.setZFPURL(""); + resultToyxVo.setZFMAIL(map.get("emailName")); + resultToyxVo.setZLYXT(""); + resultToyxVoList.add(resultToyxVo); + } + return resultToyxVoList; + } + + public static Map convertInvoiceType(){ + Map map = Maps.newHashMap(); + //10 增值税专用发票,11 增值税普通发票 ,12 增值税电子普通发票 ,13 增值税普通发票(卷票), + // 14 机动车销售统一发票,15 二手车销售统一发票,16 定额发票,17 机打发票,18 出租车发票 , + // 19 火车票 ,20 客运汽车,21 航空运输电子客票行程单 ,22 过路费发票 , + // 24 增值税电子普通发票(通行费)25 增值税电子专用发票,26 电子发票(增值税专用发票) , + // 27 电子发票(普通发票),28 船票 区块链发票 海关缴款书 + //增值税专用发票: 01,增值税普通发票:04,增值税电子专用发票:08,增值税普通发票(电子):10, + // 增值税普通发票(卷式):11,通行费发票:14,出租车票:91,火车票:92,飞机票:93,汽车票:94, + // 定额发票:95,国际小票:96,通用机打票:97,过路过桥:98,机动车销售统一发票:03,二手车销售统一发票:15, + // 可报销其他发票:85,滴滴出行行程单:86,完税证明:87,船票:88,其他:00 + map.put("01","10"); + map.put("04","11"); + map.put("10","12"); + map.put("11","13"); + map.put("03","14"); + map.put("15","15"); + map.put("95","16"); + map.put("96","17"); + map.put("91","18"); + map.put("92","19"); + map.put("94","20"); + map.put("93","21"); + map.put("","22"); + map.put("14","24"); + map.put("04","25"); + map.put("31","26"); + map.put("32","27"); + map.put("88","28"); + return map; + } + + @Test + void mailAuth() { + } +} \ No newline at end of file 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 index 7a907359..8ae7d7c2 100644 --- a/dxhy-core/src/main/java/com/dxhy/core/util/EmailParseUtils.java +++ b/dxhy-core/src/main/java/com/dxhy/core/util/EmailParseUtils.java @@ -1,8 +1,10 @@ package com.dxhy.core.util; import com.dxhy.common.utils.Base64Encoding; +import com.google.common.collect.Maps; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.StringUtils; +import org.jetbrains.annotations.NotNull; import javax.mail.*; import javax.mail.internet.InternetAddress; @@ -12,6 +14,7 @@ import javax.mail.internet.MimeUtility; import java.io.*; import java.text.SimpleDateFormat; import java.util.Date; +import java.util.List; import java.util.Map; public class EmailParseUtils { @@ -249,7 +252,7 @@ public class EmailParseUtils { * @throws FileNotFoundException * @throws IOException */ - public static void saveAttachment(Part part, Map mapLog) throws UnsupportedEncodingException, MessagingException, IOException { + public static void saveAttachment(@NotNull Part part, List> mapList) throws UnsupportedEncodingException, MessagingException, IOException { if (part.isMimeType("multipart/*")) { Multipart multipart = (Multipart) part.getContent(); //复杂体邮件 //复杂体邮件包含多个邮件体 @@ -258,22 +261,34 @@ public class EmailParseUtils { //获得复杂体邮件中其中一个邮件体 BodyPart bodyPart = multipart.getBodyPart(i); String fileName = decodeText(bodyPart.getFileName()); + Map mapLog = Maps.newHashMap(); mapLog.put("fileName",fileName); String contentType = bodyPart.getContentType(); //某一个邮件体也有可能是由多个邮件体组成的复杂体 String disp = bodyPart.getDisposition(); if (disp != null && (disp.equalsIgnoreCase(Part.ATTACHMENT) || disp.equalsIgnoreCase(Part.INLINE))) { - if ((StringUtils.isNotBlank(contentType)) && (contentType.toUpperCase().contains("PDF") || contentType.toUpperCase().contains("OFD"))){ + if ((StringUtils.isNotBlank(contentType)) && + (contentType.toUpperCase().contains("PDF") || contentType.toUpperCase().contains("OFD"))){ InputStream is = bodyPart.getInputStream(); byte[] pdfStream = IOUtils.toByteArray(is); - mapLog.put("pdfStream", Base64Encoding.encodeToString(pdfStream)); mapLog.put("contentType", contentType.toUpperCase().contains("PDF")?"PDF":"OFD"); - break; + if(pdfStream != null){ + mapLog.put("pdfStream", Base64Encoding.encodeToString(pdfStream)); + mapList.add(mapLog); + } + }else if (StringUtils.isNotBlank(fileName) && "application/octet-stream".equals(contentType) && (fileName.endsWith("pdf") || fileName.endsWith("ofd"))){ + InputStream is = bodyPart.getInputStream(); + byte[] pdfStream = IOUtils.toByteArray(is); + mapLog.put("contentType", contentType.toUpperCase().contains("PDF")?"PDF":"OFD"); + if(pdfStream != null){ + mapLog.put("pdfStream", Base64Encoding.encodeToString(pdfStream)); + mapList.add(mapLog); + } }else { continue; } } else if (bodyPart.isMimeType("multipart/*")) { - saveAttachment(bodyPart, mapLog); + saveAttachment(bodyPart, mapList); } else { // if (contentType.indexOf("name") != -1 || contentType.indexOf("application") != -1) { // saveFile(bodyPart.getInputStream(), destDir, decodeText(bodyPart.getFileName())); @@ -281,7 +296,7 @@ public class EmailParseUtils { } } } else if (part.isMimeType("message/rfc822")) { - saveAttachment((Part) part.getContent(), mapLog); + saveAttachment((Part) part.getContent(), mapList); } } diff --git a/dxhy-core/src/main/resources/mapper/mailGather/EmailMaintainMapper.xml b/dxhy-core/src/main/resources/mapper/mailGather/EmailMaintainMapper.xml index 08a2d3f2..fe570e0e 100644 --- a/dxhy-core/src/main/resources/mapper/mailGather/EmailMaintainMapper.xml +++ b/dxhy-core/src/main/resources/mapper/mailGather/EmailMaintainMapper.xml @@ -5,6 +5,7 @@ + @@ -19,7 +20,7 @@ @@ -27,7 +28,7 @@