123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619 |
- package com.jiayue.biz.service.impl;
- import java.io.*;
- import java.security.Security;
- import java.text.SimpleDateFormat;
- import java.util.*;
- import java.util.stream.Collectors;
- import javax.mail.*;
- import javax.mail.internet.InternetAddress;
- import javax.mail.internet.MimeMessage;
- import javax.mail.internet.MimeMultipart;
- import javax.mail.internet.MimeUtility;
- import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
- import com.jiayue.biz.domain.Email;
- import com.jiayue.biz.domain.EmailWindTowerInfo;
- import com.jiayue.biz.domain.WindTowerInfo;
- import com.jiayue.biz.mapper.EmailMapper;
- import com.jiayue.biz.service.EmailService;
- import com.jiayue.biz.service.EmailWindTowerInfoService;
- import com.jiayue.biz.util.FileUtil;
- import com.sun.mail.imap.IMAPFolder;
- import com.sun.mail.imap.IMAPStore;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.stereotype.Service;
- /**
- * 使用imap协议获取未读邮件数
- *
- * @author w
- */
- @Slf4j
- @Service
- public class EmailImpl extends ServiceImpl<EmailMapper, Email> implements EmailService {
- @Value("${email.user}")
- private String user;
- @Value("${email.password}")
- private String password;
- @Value("${email.host}")
- private String host;
- @Value("${email.path}")
- private String path;
- @Value("${file.outPutDir}")
- private String outPutDir;
- @Autowired
- EmailService emailService;
- private final WindTowerInfoServiceImpl windTowerInfoService;
- private final EmailWindTowerInfoService emailWindTowerInfoService;
- private final AnalysisDataImpl analysisDataService;
- public EmailImpl(WindTowerInfoServiceImpl windTowerInfoService, EmailWindTowerInfoService emailWindTowerInfoService, AnalysisDataImpl analysisDataService) {
- this.windTowerInfoService = windTowerInfoService;
- this.emailWindTowerInfoService = emailWindTowerInfoService;
- this.analysisDataService = analysisDataService;
- }
- /**
- * 获取所有邮件账号信息
- *
- * @return
- */
- public List<Email> selectEmail() {
- return emailService.list();
- }
- public void readMail() {
- List<Email> emails = this.selectEmail();
- for (Email email : emails) {
- user = email.getUserName();
- password = email.getPassword();
- host = email.getHost();
- path = email.getPath();
- Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
- Properties prop = System.getProperties();
- prop.put("mail.imap.port", "993");
- prop.put("mail.imap.ssl.enable", true);
- //如果设置,并且未指定套接字工厂,则启用MailSSLSocketFactory的使用。 如果设置为“ *”,则所有主机都是受信任的。
- //如果设置为以空格分隔的主机列表,则这些主机是可信任的。 否则,信任取决于服务器提供的证书。(设置主机可信任)
- prop.put("mail.imap.ssl.trust", host);
- //这部分就是解决异常的关键所在,设置IAMP ID信息
- HashMap IAM = new HashMap();
- //带上IMAP ID信息,由key和value组成,例如name,version,vendor,support-email等。
- // 这个value的值随便写就行
- IAM.put("name", "myname");
- IAM.put("version", "1.0.0");
- IAM.put("vendor", "myclient");
- IAM.put("support-email", "testmail@test.com");
- try {
- Session session = Session.getDefaultInstance(prop, null);
- session.setDebug(false);
- IMAPStore store = (IMAPStore) session.getStore("imap"); // 使用imap会话机制,连接服务器
- store.connect(host, user, password);
- store.id(IAM);
- IMAPFolder folder = (IMAPFolder) store.getFolder("INBOX"); // 收件箱
- /* Folder.READ_ONLY:只读权限
- * Folder.READ_WRITE:可读可写(可以修改邮件的状态)
- */
- folder.open(Folder.READ_WRITE); //打开收件箱
- // 获得收件箱中的未读邮件数
- log.warn("未读邮件数: {}", folder.getUnreadMessageCount());
- log.warn("总邮件个数: {}", folder.getMessageCount());
- Message[] messages1 = folder.getMessages();
- for (Message message : messages1) {
- //存在附件返回true 不存在返回false
- Flags flags = message.getFlags();
- if (flags.contains(Flags.Flag.SEEN)) {
- } else {
- //未读
- Multipart m = (Multipart) message.getContent();
- for (int s = 0; s < m.getCount(); s++) {
- BodyPart mimeMultipart = m.getBodyPart(s);
- log.info(mimeMultipart.getFileName());
- }
- //解析邮件
- parseMessage(message);
- }
- }
- //得到收件箱中的所有邮件并且删除邮件
- //deleteMessage(messages);
- //释放资源
- folder.close(true);
- store.close();
- } catch (Exception e) {
- log.error("读取邮件异常" + e);
- }
- }
- }
- public void parseMessage(Message... messages) throws MessagingException, IOException, InterruptedException {
- if (messages == null || messages.length < 1)
- throw new MessagingException("未找到要解析的邮件!");
- String subject = "";
- // 解析所有邮件
- for (int i = 0, count = messages.length; i < count; i++) {
- MimeMessage msg = (MimeMessage) messages[i];
- log.info("------------------解析第" + msg.getMessageNumber() + "封邮件-------------------- ");
- //获取邮件主题
- subject = getSubject(msg);
- boolean isContainerAttachment = isContainAttachment(msg);
- File file = new File(path);
- if (!file.exists()) {
- file.mkdirs();
- }
- if (isContainerAttachment) {
- saveAttachment(msg, path); //保存附件
- }
- StringBuffer content = new StringBuffer(30);
- //解析邮件正文
- getMailTextContent(msg, content);
- //邮件设置为已读
- isTrue(msg);
- log.info("------------------第" + msg.getMessageNumber() + "封邮件解析结束-------------------- ");
- }
- //执行系统命令转为txt文件sdf.parse("20220428")
- systemCommand(subject);
- }
- /**
- * 获得邮件主题
- *
- * @param msg 邮件内容
- * @return 解码后的邮件主题
- */
- public String getSubject(MimeMessage msg) throws UnsupportedEncodingException, MessagingException {
- return MimeUtility.decodeText(msg.getSubject());
- }
- /**
- * 获得邮件发件人
- *
- * @param msg 邮件内容
- * @return 姓名 <Email地址>
- * @throws MessagingException
- * @throws UnsupportedEncodingException
- */
- public 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;
- }
- /**
- * 根据收件人类型,获取邮件收件人、抄送和密送地址。如果收件人类型为空,则获得所有的收件人
- * <p>Message.RecipientType.TO 收件人</p>
- * <p>Message.RecipientType.CC 抄送</p>
- * <p>Message.RecipientType.BCC 密送</p>
- *
- * @param msg 邮件内容
- * @param type 收件人类型
- * @return 收件人1 <邮件地址1>, 收件人2 <邮件地址2>, ...
- * @throws MessagingException
- */
- public 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 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 part 邮件内容
- * @return 邮件中存在附件返回true,不存在返回false
- * @throws MessagingException
- * @throws IOException
- */
- public 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;
- }
- /**
- * 判断邮件是否已读 imap有效 pop3无效
- *
- * @param msg 邮件内容
- * @return 如果邮件已读返回true, 否则返回false
- * @throws MessagingException
- */
- public boolean isSeen(MimeMessage msg) throws MessagingException {
- return msg.getFlags().contains(Flags.Flag.SEEN);
- }
- /**
- * 设置邮件为已读
- *
- * @param msg 邮件内容
- * @throws MessagingException
- */
- public void isTrue(MimeMessage msg) throws MessagingException {
- msg.setFlag(Flags.Flag.SEEN, true);
- }
- /**
- * 判断邮件是否需要阅读回执
- *
- * @param msg 邮件内容
- * @return 需要回执返回true, 否则返回false
- * @throws MessagingException
- */
- public 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 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 void getMailTextContent(Part part, StringBuffer content) throws MessagingException, IOException {
- //如果是文本类型的附件,通过getContent方法可以取到文本内容,但这不是我们需要的结果,所以在这里要做判断
- boolean isContainTextAttach = part.getContentType().indexOf("name") > 0;
- if (part.isMimeType("text/*") && !isContainTextAttach) {
- try{
- content.append(part.getContent().toString());
- }catch(UnsupportedEncodingException e) {
- InputStream is = part.getInputStream();
- content.append(inputStream2String(is));
- }
- } 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);
- }
- }
- }
- //处理编码错误问题
- public static String inputStream2String(InputStream in)throws IOException {
- StringBuffer out = new StringBuffer();
- byte[] b = new byte[4096];
- for(int n; (n=in.read(b))!=-1;){
- out.append(new String(b,0,n));
- }
- return out.toString();
- }
- /**
- * 保存附件
- *
- * @param part 邮件中多个组合体中的其中一个组合体
- * @param destDir 附件保存目录
- * @throws UnsupportedEncodingException
- * @throws MessagingException
- * @throws FileNotFoundException
- * @throws IOException
- */
- public void saveAttachment(Part part, String destDir) throws MessagingException, 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 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 String decodeText(String encodeText) throws UnsupportedEncodingException {
- if (encodeText == null || "".equals(encodeText)) {
- return "";
- } else {
- return MimeUtility.decodeText(encodeText);
- }
- }
- /**
- * 执行命令通过软件解压rld文件到D:\out\new\下
- */
- public void systemCommand(String subjectId) {
- try {
- Runtime runtime = Runtime.getRuntime();
- File file = new File("D:\\in\\");
- //遍历所有文件
- File[] files = file.listFiles();
- for (File f : files) {
- String type = f.getName().substring(f.getName().lastIndexOf(".") + 1);
- if (type.equals("RWD")) {
- //RWD文件类型
- String id = f.getName().substring(0, 4);
- //根据编号过滤
- List<WindTowerInfo> windTowerInfoList = windTowerInfoService.getByEquipmentNo(id);
- //没有这个编号的塔
- windTowerInfoType(id,windTowerInfoList);
- for (WindTowerInfo w : windTowerInfoList) {
- if (id.equals(w.getEquipmentNo())) {
- if (w.getPassword().equals("")) {
- log.error("该测风塔没有配置密码");
- } else {
- String password = w.getPassword();
- String cmd = "\"D:\\NRG\\SymDR\\SDR.exe\"" + " /z " + password + " " + f.getPath();
- Process ipconfig = runtime.exec(cmd);
- ipconfig.waitFor();
- InputStream inputStream = ipconfig.getInputStream();
- byte[] bytes = new byte[1024];
- int len = 0;
- while ((len = inputStream.read(bytes)) != -1) {
- log.info(new String(bytes, 0, len, "GBK"));
- }
- }
- }
- }
- //转换成txt的文件在D:\NRG\ScaledData\目录下 移动到 D:\out\下 转换文件后会有两个文件一个txt 一个log 删除log 移动txt
- File file1 = new File("D:\\NRG\\ScaledData\\");
- File[] files1 = file1.listFiles();
- for (File e : files1) {
- String[] name = e.getName().split("\\.");
- if (name[1].equals("txt")) {
- FileUtil.move(e.getPath(), "D:\\out\\new\\");
- } else {
- e.delete();
- }
- }
- //转成txt后把文件移动到系统文件备份目录下
- //xls移动系统文件目录下
- this.tranFile();
- //把txt文件转成excel文件并解析
- analysisDataService.analysisData(type);
- } else if(type.equals("rld")){
- //rld文件类型
- String[] id = f.getName().split("_");
- //根据编号过滤
- List<WindTowerInfo> windTowerInfoList = windTowerInfoService.getByEquipmentNo(id[0]);
- windTowerInfoType(id[0],windTowerInfoList);
- //如果有 有可能会有编号相同 但是记录仪编号不同的情况 不解析看不到记录仪编号 所以只能用相同编号的测风塔密码解析
- //如果是从邮件里读到的塔新增的话是没有数据密码的 所以需要人为的手动配置密码
- for (WindTowerInfo w : windTowerInfoList) {
- if (id[0].equals(w.getEquipmentNo())) {
- if ("".equals(w.getPassword())) {
- log.error(w.getEquipmentNo() + "测风塔没有配置数据密码");
- } else {
- String[] s = new String[]{
- "\"D:\\Program Files (x86)\\Renewable NRG Systems\\SymPRO Desktop\\SymPRODesktop.exe\"",
- "/cmd", "convert", "/file", f.getPath(),
- "/pass", w.getPassword(), "/type", "\"meas\"", "/outputdir", "\"D:\\out\\new\""
- };
- Process ipconfig = runtime.exec(s);
- ipconfig.waitFor();
- InputStream inputStream = ipconfig.getInputStream();
- byte[] bytes = new byte[1024];
- int len = 0;
- while ((len = inputStream.read(bytes)) != -1) {
- log.info(new String(bytes, 0, len, "GBK"));
- }
- }
- }
- }
- //转成txt后把文件移动到系统文件备份目录下
- //xls移动系统文件目录下
- this.tranFile();
- //把txt文件转成excel文件并解析
- analysisDataService.analysisData(type);
- }else if(type.equals("csv")){
- if(!subjectId.contains("[") || !subjectId.contains("]")){
- cn.hutool.core.io.FileUtil.del(f);
- continue;
- }
- String id = subjectId.substring(subjectId.indexOf("[") + 1, subjectId.lastIndexOf("]"));
- List<WindTowerInfo> equipmentNo = windTowerInfoService.getByEquipmentNo(id);
- if(equipmentNo.size() == 0){
- windTowerInfoType(id,equipmentNo);
- }else {
- analysisDataService.acousticRadar(f,id);
- }
- }else if(type.equals("dat")){
- analysisDataService.parseByDat(f);
- }
- }
- } catch (Exception e) {
- log.error("执行系统命令失败:" + e);
- }
- }
- //检测是否存在
- public void windTowerInfoType(String id, List<WindTowerInfo> windTowerInfoList) {
- //没有这个编号的塔
- if (windTowerInfoList.size() == 0) {
- List<EmailWindTowerInfo> emailWindTowerInfos = emailWindTowerInfoService.list().stream().filter(wind -> wind.getEquipmentNo().equals(id)).collect(Collectors.toList());
- if (emailWindTowerInfos.size() == 0) {
- //如果测风塔里面没有这个塔并且邮件测风塔里也没有这个塔 则添加到邮箱读取的测风塔表中
- EmailWindTowerInfo emailWindTowerInfo = new EmailWindTowerInfo();
- emailWindTowerInfo.setEquipmentNo(id);
- emailWindTowerInfoService.save(emailWindTowerInfo);
- log.info(id + " 测风塔信息里没有这个的塔 并且邮件测风塔里也没有这个塔");
- } else {
- log.info(id + " 测风塔信息里没有这个的塔 邮件测风塔里已存在这个塔");
- }
- }
- }
- //转移文件
- public void tranFile() throws Exception {
- //转成txt后把文件移动到系统文件备份目录下
- File file1 = new File("D:\\in\\");
- File[] files1 = file1.listFiles();
- //xls移动系统文件目录下
- for (File e : files1) {
- String[] str = e.getName().split("\\.");
- if (str[1].equals("RWD")) {
- FileUtil.move(e.getPath(), FileUtil.getSystemFilePath() + File.separator + str[0].substring(0, 4));
- } else {
- String[] strs = str[0].split("_");
- FileUtil.move(e.getPath(), FileUtil.getSystemFilePath() + File.separator + strs[0]);
- }
- }
- }
- }
|