feature 1.邮箱采集功能完善

release
zhenghaiyang@ele-cloud.com 2 years ago
parent 2c87e0d454
commit 5393ffb144
  1. 10
      dxhy-common/src/main/java/com/dxhy/common/util/FileUtil.java
  2. 3
      dxhy-core/src/main/java/com/dxhy/core/model/mailGather/EmailMaintainVo.java
  3. 44
      dxhy-core/src/main/java/com/dxhy/core/model/mailGather/OcrResultToyxVo.java
  4. 6
      dxhy-core/src/main/java/com/dxhy/core/model/openservice/OpenServiceOcr.java
  5. 8
      dxhy-core/src/main/java/com/dxhy/core/service/mailGather/impl/EmailMaintainServiceImpl.java
  6. 114
      dxhy-core/src/main/java/com/dxhy/core/service/openservice/impl/OpenServicePlatformServiceImpl.java
  7. 61
      dxhy-core/src/main/java/com/dxhy/core/service/openservice/model/ocr/OcrDataTypeEnum.java
  8. 43
      dxhy-core/src/main/java/com/dxhy/core/task/SnEmailGatherTask.java
  9. 201
      dxhy-core/src/main/java/com/dxhy/core/task/SnEmailGatherTaskTest.java
  10. 27
      dxhy-core/src/main/java/com/dxhy/core/util/EmailParseUtils.java
  11. 24
      dxhy-core/src/main/resources/mapper/mailGather/EmailMaintainMapper.xml
  12. 10
      dxhy-sign/src/main/java/com/dxhy/sign/controller/SignFpqsController.java
  13. 2
      dxhy-sign/src/main/java/com/dxhy/sign/service/fpqs/impl/SignFpqsServiceImpl.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 = "";

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

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

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

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

@ -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<OpenServiceOcr> 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<OcrDataListEntity> ocrDataListEntities = ocrResponseVo.getResult().getObjectList();
return dxOcrConvertSnOcr(ocrDataListEntities);
}
}
return null;
}
//实现实体类转换
public List<OpenServiceOcr> dxOcrConvertSnOcr(List<OcrDataListEntity> ocrDataListEntities){
public static List<OpenServiceOcr> dxOcrConvertSnOcr(List<OcrDataListEntity> ocrDataListEntities){
List<OpenServiceOcr> openServices = Lists.newArrayList();
for (OcrDataListEntity ocrDataListEntity : ocrDataListEntities) {
OpenServiceOcr serviceOcr = new OpenServiceOcr();
List<List<OcrProductListEntity>> productList = ocrDataListEntity.getProductList();
List<OcrItemListEntity> itemList = ocrDataListEntity.getItemList();
String type = ocrDataListEntity.getType();
if("other".equals(type)){
break;
}
Map<String, String> 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<OpenServiceOcr.InvoiceOcrDetail> invoiceOcrDetailList = Lists.newArrayList();
for (List<OcrProductListEntity> productListEntities : productList) {
for (List<OcrProductListEntity> productListEntities: productList) {
Map<String, String> 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<OpenServiceOcr.InvoiceOcrDetail> invoiceOcrDetailList = Lists.newArrayList();
for (List<OcrProductListEntity> productListEntities : productList) {
Map<String, String> 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);
}

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

@ -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<String, String> map = Maps.newHashMap();
EmailParseUtils.saveAttachment(msg, map);
gatherLogVo.setFileType(map.get("contentType"));
gatherLogVo.setFileName(map.get("fileName"));
String pdfStream = map.get("pdfStream");
List<OpenServiceOcr> 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<Map<String, String>> 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<OpenServiceOcr> 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);
}
}
}

@ -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<Map<String, String>> mapList = Lists.newArrayList();
EmailParseUtils.saveAttachment(msg, mapList);
for (Map<String, String> map : mapList) {
map.put("emailName",emailName);
String pdfStream = map.get("pdfStream");
if(StringUtils.isNotBlank(pdfStream)){
List<OpenServiceOcr> 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<OcrResultToyxVo> convertToOcrResult(List<OpenServiceOcr> openServiceOcrs, Map<String, String> map){
List<OcrResultToyxVo> 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<String, String> 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<String, String> convertInvoiceType(){
Map<String, String> 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() {
}
}

@ -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<String, String> mapLog) throws UnsupportedEncodingException, MessagingException, IOException {
public static void saveAttachment(@NotNull Part part, List<Map<String, String>> 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<String, String> 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);
}
}

@ -5,6 +5,7 @@
<resultMap type="com.dxhy.core.model.mailGather.EmailMaintainVo" id="EmailMaintainMap">
<result property="id" column="id" jdbcType="VARCHAR"/>
<result property="deptId" column="dept_id" jdbcType="VARCHAR"/>
<result property="companyCode" column="company_code" jdbcType="VARCHAR"/>
<result property="deptName" column="dept_name" jdbcType="VARCHAR"/>
<result property="username" column="username" jdbcType="VARCHAR"/>
<result property="userId" column="user_id" jdbcType="VARCHAR"/>
@ -19,7 +20,7 @@
<!--查询单个-->
<select id="queryAll" resultMap="EmailMaintainMap">
select
id, dept_id, dept_name, username, user_id, email_address, email_password, email_uid, create_time, del_status, modify_time
id, dept_id, company_code, dept_name, username, user_id, email_address, email_password, email_uid, create_time, del_status, modify_time
from email_maintain
where del_status = '0';
</select>
@ -27,7 +28,7 @@
<!--查询指定行数据-->
<select id="queryAllByLimit" resultMap="EmailMaintainMap" parameterType="java.util.Map">
select
id, dept_id, dept_name, username, user_id, email_address, create_time, del_status, modify_time
id, dept_id, company_code, dept_name, username, user_id, email_address, create_time, del_status, modify_time
from email_maintain
<where>
<if test="deptId != null and deptId != ''">
@ -50,6 +51,9 @@
<if test="deptId != null and deptId != ''">
and dept_id = #{deptId}
</if>
<if test="companyCode != null and companyCode != ''">
and company_code = #{companyCode}
</if>
<if test="deptName != null and deptName != ''">
and dept_name = #{deptName}
</if>
@ -79,26 +83,27 @@
<!--新增所有列-->
<insert id="insert" keyProperty="id" useGeneratedKeys="true">
insert into email_maintain(dept_id, dept_name, username, user_id, email_address, email_password, create_time, del_status, modify_time)
values (#{deptId}, #{deptName}, #{username}, #{userId}, #{emailAddress}, #{emailPassword}, #{createTime}, #{delStatus}, #{modifyTime})
insert into email_maintain(dept_id, company_code, dept_name, username, user_id, email_address, email_password, create_time, del_status, modify_time)
values (#{deptId}, #{companyCode}, #{deptName}, #{username}, #{userId}, #{emailAddress}, #{emailPassword}, #{createTime}, #{delStatus}, #{modifyTime})
</insert>
<insert id="insertBatch" keyProperty="id" useGeneratedKeys="true">
insert into email_maintain(dept_id, dept_name, username, user_id, email_address, email_password, create_time, del_status, modify_time)
insert into email_maintain(dept_id, company_code, dept_name, username, user_id, email_address, email_password, create_time, del_status, modify_time)
values
<foreach collection="entities" item="entity" separator=",">
(#{entity.deptId}, #{entity.deptName}, #{entity.username}, #{entity.userId}, #{entity.emailAddress}, #{entity.emailPassword}, #{entity.createTime}, #{entity.delStatus}, #{entity.modifyTime})
(#{entity.deptId}, #{entity.companyCode}, #{entity.deptName}, #{entity.username}, #{entity.userId}, #{entity.emailAddress}, #{entity.emailPassword}, #{entity.createTime}, #{entity.delStatus}, #{entity.modifyTime})
</foreach>
</insert>
<insert id="insertOrUpdateBatch" keyProperty="id" useGeneratedKeys="true">
insert into email_maintain(dept_id, dept_name, username, user_id, email_address, email_password, create_time, del_status, modify_time)
insert into email_maintain(dept_id, company_code, dept_name, username, user_id, email_address, email_password, create_time, del_status, modify_time)
values
<foreach collection="entities" item="entity" separator=",">
(#{entity.deptId}, #{entity.deptName}, #{entity.username}, #{entity.userId}, #{entity.emailAddress}, #{entity.emailPassword}, #{entity.createTime}, #{entity.delStatus}, #{entity.modifyTime})
(#{entity.deptId}, #{entity.companyCode}, #{entity.deptName}, #{entity.username}, #{entity.userId}, #{entity.emailAddress}, #{entity.emailPassword}, #{entity.createTime}, #{entity.delStatus}, #{entity.modifyTime})
</foreach>
on duplicate key update
dept_id = values(dept_id),
company_code = values(company_code),
dept_name = values(dept_name),
username = values(username),
user_id = values(user_id),
@ -115,6 +120,9 @@
<set>
<if test="deptId != null and deptId != ''">
dept_id = #{deptId},
</if>
<if test="companyCode != null and companyCode != ''">
company_code = #{companyCode},
</if>
<if test="deptName != null and deptName != ''">
dept_name = #{deptName},

@ -129,7 +129,7 @@ public class SignFpqsController extends AbstractController {
* @return 返回结果
*
*/
@RequestMapping("/sgqs/sendEmailByQs")
@RequestMapping("/sign/sendEmailByQs")
@ResponseBody
@SysLog("手工签收--邮箱签收")
public ResponseEntity<?> sendEmailByQs(@RequestBody Map<String, Object> pramsMap) {
@ -142,7 +142,7 @@ public class SignFpqsController extends AbstractController {
return ResponseEntity.ok(signFpqsService.qsSendEmail(pramsMap));
}
@RequestMapping("/qsExport")
@RequestMapping("/sign/qsExport")
public void qsExport(@RequestBody Map<String, Object> pramsMap, HttpServletResponse response){
if (pramsMap.get("ids") == null || "".equals(pramsMap.get("ids"))) {
// return ResponseEntity.ok(R.error("请选择发票数据"));
@ -164,9 +164,9 @@ public class SignFpqsController extends AbstractController {
log.error("签收数据导出,错误日志:{}",e);
} finally {
// 千万别忘记finish 会帮忙关闭流
if (excelWriter != null) {
excelWriter.finish();
}
// if (excelWriter != null) {
// excelWriter.close();
// }
if(outputStream != null){
try {
outputStream.close();

@ -3355,7 +3355,7 @@ public class SignFpqsServiceImpl extends MpBaseServiceImpl<SignRecordInvoiceDao,
public List<QsExcelEntity> selectWqsfp(Map<String, Object> pramsMap) {
DynamicContextHolder.push(pramsMap.get("dbName") + DbConstant.BUSINESS_READ);
DynamicContextHolder.push("business_business_read");
if(pramsMap.get("ids") != null){
String[] ids = String.valueOf(pramsMap.get("ids")).split(",");
List<String> strings = Arrays.asList(ids);

Loading…
Cancel
Save