/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package cn.com.bsw.btpls;
import cn.com.bsw.btpls.acluser.action.AclUserAction;
import cn.com.bsw.btpls.common.constant.CustomsDeclarationState;
import cn.com.bsw.btpls.customscover.dao.CustomsCoverDao;
import cn.com.bsw.btpls.customscover.entity.CustomsCoverHead;
import cn.com.bsw.btpls.customscover.logic.CustomsCoverLogic;
import cn.com.bsw.btpls.customsdeclaration.dao.CustomsDeclarationDao;
import cn.com.bsw.btpls.customsdeclaration.entity.CustomsDeclarationHead;
import cn.com.bsw.btpls.database.logic.DataBaseLogic;
import cn.com.bsw.btpls.indenture.dao.IndentureDao;
import cn.com.bsw.btpls.indenture.logic.IndentureLogic;
import cn.com.bsw.btpls.message.dao.MessageQueryDao;
import cn.com.bsw.btpls.systemconfigure.dao.SystemConfigureDao;
import cn.com.bsw.btpls.systemconfigure.entity.ApplyContact;
import cn.com.bsw.btpls.systemconfigure.entity.CustomsContact;
import cn.com.bsw.btpls.systemconfigure.entity.SystemConfigure;
import java.lang.reflect.InvocationTargetException;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;
import javax.ejb.EJB;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import org.apache.commons.beanutils.PropertyUtils;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
/**
* 自动对账
*
* @author lzj
*/
public class AutoSendWarnningEmail extends HttpServlet {
@EJB
private IndentureLogic indentureLogic = null;
@EJB
private IndentureDao indentureDao = null;
@EJB
private CustomsCoverDao customsCoverDao;
@EJB
private CustomsDeclarationDao customsDeclarationDao;
@EJB
private MessageQueryDao messageQueryDao;
private Logger log = Logger.getLogger(AutoSendWarnningEmail.class.getName());
@EJB
private AclUserAction userLogic = null;
@EJB
private DataBaseLogic dataBaseLogic = null;
@EJB
private SystemConfigureDao systemConfigureDao;
@EJB
private CustomsCoverLogic customsCoverLogic;
private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
private DecimalFormat df = new DecimalFormat("#.00");
private ExecutorService executor;
/**
* 是否执行
*/
private boolean isExcuting = true;
@Override
public void destroy() {
isExcuting = false;
if (executor != null && !executor.isShutdown()) {
executor.shutdown();
}
System.out.println("自动发送邮件线程退出!");
Logger.getLogger("自动发送邮件线程退出!");
super.destroy();
}
@Override
public void init() throws ServletException {
super.init();
Logger.getLogger("正在初始化自动发送邮件线程!");
executor = Executors.newFixedThreadPool(10);//最多10个线程用于发送邮件(发送邮件等待时间比较长)
ProcessThread thread = new ProcessThread();
thread.setPriority(Thread.NORM_PRIORITY);
thread.start();
Logger.getLogger("初始化自动发送邮件线程结束!");
}
class MailSenderKH implements Runnable {
String[] customsEmail;
String khName;
String khCode;
String msg;
public MailSenderKH(String[] customsEmail, String khName, String khCode, String msg) {
this.customsEmail = customsEmail;
this.khName = khName;
this.khCode = khCode;
this.msg = msg;
}
public void run() {
try {
sendEmail(customsEmail, null,
msg);
log.info("信息:----自动发送邮件成功!转入方公司编码为:【" + khCode + "】的预警信息发送成功。");
} catch (Exception e) {
e.printStackTrace();
log.info("信息:----自动发送邮件出错!转入方公司编码为:【" + khCode + "】的预警信息发送失败。");
//若发送出错,继续
}
}
}
class MailSenderGYS implements Runnable {
String compantInfo;
List<String> tempAppls;
String msg;
public MailSenderGYS(String compantInfo, List<String> tempAppls, String msg) {
this.compantInfo = compantInfo;
this.tempAppls = tempAppls;
this.msg = msg;
}
public void run() {
try {
String companycode = compantInfo.split(",")[1];
sendEmail(tempAppls.toArray(new String[tempAppls.size()]), null,
msg);
log.info("信息:----自动发送邮件成功!转出方公司编码为:【" + companycode + "】的预警信息发送成功。");
} catch (Exception e) {
e.printStackTrace();
log.info("信息:----自动发送邮件出错!转出方公司编码为:【" + compantInfo.split(",")[1] + "】的预警信息发送失败。");
}
}
}
class ProcessThread extends Thread {
long currendTime = 0;
Date nowDate = null;
@Override
public void run() {
while (isExcuting) {
//----------获得服务器日期----------
nowDate = indentureDao.getNowTime();
try {
currendTime = calcSleepMilis(nowDate);
currentThreadTime(currendTime);
//以下是发送查询是否存在预警信息信息,并发送
List<ApplyContact> suppliers = systemConfigureDao.findApplyContactList(null);
List<CustomsContact> customers = systemConfigureDao.findAllData(CustomsContact.class.getName());
List<SystemConfigure> systemConfigures = systemConfigureDao.findAllData(SystemConfigure.class.getName());
//筛选出所有转入方email
List<String> customsEmail = new ArrayList<String>();
for (CustomsContact customsContact : customers) {
String email = customsContact.geteMail();
if (email != null && !"".equals(email.trim())) {
if (checkEmail(email)) {//筛选掉不合法的email
if (!customsEmail.contains(email)) {
customsEmail.add(email);
}
}
}
}
//筛选出转出方的企业和email
Map applEmail = new HashMap();
for (ApplyContact applyContact : suppliers) {
String email = applyContact.getContEMail();
if (email == null || "".equals(email.trim())) {
continue;
}
if (!checkEmail(email)) {//筛选掉不合法的email
continue;
}
String compantInfo = applyContact.getCompanyName() + "," + applyContact.getCompanyCode() + "," + applyContact.getKhName() + "," + applyContact.getKhCode();
if (applEmail.get(compantInfo) == null) {
List<String> emailList = new ArrayList<String>();
emailList.add(email);
applEmail.put(compantInfo, emailList);
} else {
List emailList = (List) applEmail.get(compantInfo);
if (!emailList.contains(email)) {
emailList.add(email);
}
}
}
//对每一个存在联系方式并且维护了email的供应商获取并发送预警信息,并把所有发给供应商的信息汇总,下面发送给转入方
for (Object temp : applEmail.keySet()) {
MailSenderGYS senderGYS = new MailSenderGYS((String) temp, ((List) applEmail.get(temp)), getMessagePerGYS((String) temp));
executor.submit(senderGYS);
}
//发送邮件到转入方
String khName = systemConfigures.get(0).getKhName();
String khCode = systemConfigures.get(0).getKhCode();
MailSenderKH senderKH = new MailSenderKH(customsEmail.toArray(new String[customsEmail.size()]), khName, khCode, getMessagePerKH(khName, khCode));
executor.submit(senderKH);
} catch (Exception ex) {
ex.printStackTrace();
log.info("信息:----自动发送邮件出错!");
}
}
}
}
public boolean checkEmail(String target) {
return Pattern.matches("\\w+@\\w+[.]\\w+", target);
}
private String toHtmlString(Object target) {
if (target == null) {
return "";
}
String temp = target + "";
if (target instanceof Double || target instanceof Float) {
temp = df.format(target);
}
if (target instanceof Date) {
temp = format.format(target);
}
temp = temp.replaceAll("&", "&");
temp = temp.replaceAll("<", "<");
temp = temp.replaceAll(">", ">");
temp = temp.replaceAll("\"", """);
return temp;
}
/**
* 拼接出一个Li标签中的一个table标签的字符串(当表格中的数据位空时返回空字符串)
*
* @param title 该分点的标题
* @param colNames 该表格的列名
* @param propNamesOrIndex 各列的属性名或者行为数组时的下标
* @param data 填充在表格中的数据
* @param render 填充时获取对应显示用的字符串
* @return
*/
private String createHtmlTableString(String title, String[] colNames, Object[] propNamesOrIndex, List data, TbRender render) {
if (data == null || data.size() <= 0) {
return "";
}
//拼接分点标题
String tableStr = "<li><span>" + title + "</span><p>";
tableStr += "<table>";
//拼接表格的列名
tableStr += "<tr>";
for (int i = 0; i < colNames.length; i++) {
tableStr += "<th>" + colNames[i] + "</th>";
}
tableStr += "</tr>";
//拼接表格的每行
for (Object row : data) {
tableStr += "<tr>";
if (row instanceof Object[]) {
Object[] tempRow = (Object[]) row;
for (int i = 0; i < colNames.length; i++) {
tableStr += "<td>";
if (render != null) {
if (propNamesOrIndex != null) {
Integer[] index = (Integer[]) propNamesOrIndex;
tableStr += toHtmlString(render.rend(i, tempRow[index[i]]));
} else {
tableStr += toHtmlString(render.rend(i, tempRow[i]));
}
} else {
if (propNamesOrIndex != null) {
Integer[] index = (Integer[]) propNamesOrIndex;
tableStr += toHtmlString(tempRow[index[i]]);
} else {
tableStr += toHtmlString(tempRow[i]);
}
}
tableStr += "</td>";
}
} else {
if (propNamesOrIndex != null) {
String[] propNames = (String[]) propNamesOrIndex;
for (String propName : propNames) {
tableStr += "<td>";
try {
if (render != null) {
tableStr += toHtmlString(render.rend(propName, PropertyUtils.getProperty(row, propName)));
} else {
tableStr += toHtmlString(PropertyUtils.getProperty(row, propName));
}
} catch (IllegalAccessException ex) {
Logger.getLogger(AutoSendWarnningEmail.class.getName()).log(Level.SEVERE, null, ex);
} catch (InvocationTargetException ex) {
Logger.getLogger(AutoSendWarnningEmail.class.getName()).log(Level.SEVERE, null, ex);
} catch (NoSuchMethodException ex) {
Logger.getLogger(AutoSendWarnningEmail.class.getName()).log(Level.SEVERE, null, ex);
}
tableStr += "</td>";
}
} else {//只有一列的情况下,直接传入字符串
tableStr += "<td>";
tableStr += toHtmlString(row);
tableStr += "</td>";
}
}
tableStr += "</tr>";
}
tableStr += "</table><br></li>";
return tableStr;
}
/**
* 把拼接出来的表格拼接都html的ul列表中
*
* @param customsName
* @param customsCode
* @param parts
* @return
*/
public String wrapLi(String customsName, String customsCode, String[] parts) {
String htmlString = "<html>"
+ "<head>"
+ "<style type=\"text/css\">"
+ "table{"
+ "background:#F6F9ED;"
+ "border: 1px solid #838B8B;"
+ "margin-left:20;"
+ "margin-top:20;"
+ "border-collapse:collapse;"
+ "}"
+ "td{"
+ "border: 1px solid #838B8B;"
+ "text-align:center;"
+ "padding:5px;"
+ "}"
+ "th{"
+ "background:#E0EEEE;"
+ "border: 1px solid #838B8B;"
+ "text-align:center;"
+ "padding:5px;"
+ "}"
+ "li{"
+ "/*border: 1px solid #838B8B;*/"
+ "margin-top:20;"
+ "padding:20;"
+ "}"
+ "div{"
+ "width:600;"
+ "}"
+ "span{"
+ ""
+ "}"
+ "</style>"
+ "</head>"
+ "<body>"
+ "尊敬的用户您好!" + customsName + "【" + customsCode + "】。<br>"
+ "<p><span>您有待处理的业务:</span><p>"
+ "<ul>";
for (String tb : parts) {
htmlString += tb;
}
htmlString += "</ul>"
+ "</body>"
+ "</html>";
return htmlString;
}
public abstract class TbRender {
public abstract String rend(Object col, Object target);
}
/**
* 把拼接出来的表格拼接都html的ul列表中
*
* @param customsName
* @param customsCode
* @param parts
* @return
*/
public String wrapLi(String companyInfo, String[] parts) {
String[] info = companyInfo.split(",");
String htmlString = "<html>"
+ "<head>"
+ "<style type=\"text/css\">"
+ "table{"
+ "background:#F6F9ED;"
+ "border: 1px solid #838B8B;"
+ "margin-left:20;"
+ "margin-top:20;"
+ "border-collapse:collapse;"
+ "}"
+ "td{"
+ "border: 1px solid #838B8B;"
+ "text-align:center;"
+ "padding:5px;"
+ "}"
+ "th{"
+ "background:#E0EEEE;"
+ "border: 1px solid #838B8B;"
+ "text-align:center;"
+ "padding:5px;"
+ "}"
+ "li{"
+ "/*border: 1px solid #838B8B;*/"
+ "margin-top:20;"
+ "padding:20;"
+ "}"
+ "div{"
+ "width:600;"
+ "}"
+ "span{"
+ ""
+ "}"
+ "</style>"
+ "</head>"
+ "<body>"
+ "尊敬的用户您好!" + info[0] + "【" + info[1] + "】,转入公司:" + info[2] + "【" + info[3] + "】。<br>"
+ "<p><span>您有待处理的业务:</span><p>"
+ "<ul>";
for (String tb : parts) {
htmlString += tb;
}
htmlString += "</ul>"
+ "</body>"
+ "</html>";
return htmlString;
}
private String getMessagePerKH(String customsName, String customsCode) {
boolean hasMessage = false;
List<CustomsCoverHead> coverHeadWait = customsCoverDao.remindKHCoverHeadWait();
hasMessage = (coverHeadWait == null || coverHeadWait.size() <= 0) ? hasMessage : true;
String coverTb = createHtmlTableString("办理转出关封存在需要办理转入关封的业务,明细信息见下表:",
new String[]{"关封号", "供应商名称", "开始日期", "截止日期"},
new String[]{"coverNO", "companyName", "startDate", "expiryDate"},
coverHeadWait, null);
List<Object[]> KHFormalIndenture = indentureDao.remindKHFormalIndenture();
hasMessage = (KHFormalIndenture == null || KHFormalIndenture.size() <= 0) ? hasMessage : true;
String IndentureTb = createHtmlTableString("收发货后存在需要办理报关的业务,明细信息见下表:",
new String[]{"转出方编码", "转出方名称", "关帐批次号", "发货日期", "截止报关日期", "离报关截止日期还剩天数"},
new Integer[]{5, 0, 1, 2, 3, 4},
KHFormalIndenture, null);
//加入供应商预警信息统计
List<String> reconciliations = indentureLogic.checkKHReconciliationTime();
hasMessage = (reconciliations == null || reconciliations.size() <= 0) ? hasMessage : true;
String recTb = createHtmlTableString("收发货对帐 : 收发货单存在需要及时对帐,明细信息见下表:",
new String[]{"对帐提醒"},
null,
reconciliations, null);
List<CustomsDeclarationHead> customsDeclaration = customsDeclarationDao.remindKHCustomsDeclaration();
hasMessage = (customsDeclaration == null || customsDeclaration.size() <= 0) ? hasMessage : true;
String CusDecTb = createHtmlTableString("转入报关后转出存在未办理报关,明细信息见下表:",
new String[]{"供应商编码", "供应商名称", "状态", "批次号", "流水号", "申请日期", "转入日期", "转入报关单号", "转出日期", "转出报关单号"},
new String[]{"companyCode", "companyName", "state", "batchNum", "serialNumber",
"sendDate", "rollInDate", "rollInCovorNO", "rollOutDate", "rollOutCovorNO"},
customsDeclaration, new TbRender() {
@Override
public String rend(Object col, Object target) {
if (col instanceof String && col.equals("state")) {
return target == null ? "" : CustomsDeclarationState.getDeclareStateName(Integer.parseInt(target.toString()));
}
return target == null ? "" : target + "";
}
});
List<String> HGDateDetail = messageQueryDao.checkHGDateDetailRemindForKH();
hasMessage = (HGDateDetail == null || HGDateDetail.size() <= 0) ? hasMessage : true;
String dateDetailTb = createHtmlTableString("供应商存在需要海关报关,明细信息见下表:",
new String[]{"申报提醒"},
null,
HGDateDetail, null);
List<String> coverExpiryMsgs = customsCoverLogic.getExpiryCustomsCover(null);
hasMessage = (coverExpiryMsgs == null || coverExpiryMsgs.size() <= 0) ? hasMessage : true;
String coverExpiryTb = createHtmlTableString("存在将要过期的关封,明细信息见下表:",
new String[]{"关封有效期提醒"},
null,
coverExpiryMsgs, null);
return hasMessage
? wrapLi(customsName, customsCode, new String[]{coverTb, IndentureTb, CusDecTb, dateDetailTb, recTb, coverExpiryTb})
: "";
}
private String getMessagePerGYS(String companyInfo) {
String[] info = companyInfo.split(",");
boolean hasMessage = false;
String temp = indentureLogic.checkGYSReconciliationTime(info[1]);
String RecPart = "";//对帐列表分点的字符串
if (!temp.equals("")) {
hasMessage = true;
RecPart += "<li>" + temp + "<p></li>";
}
List<CustomsDeclarationHead> customsDeclaration = customsDeclarationDao.remindGYSCustomsDeclaration(info[1]);
hasMessage = (customsDeclaration == null || customsDeclaration.size() <= 0) ? hasMessage : true;
String CusDecTb = createHtmlTableString("转入报关后转出存在未办理报关,明细信息见下表:",
new String[]{"状态", "批次号", "流水号", "申请日期", "转入日期", "转入报关单号", "转出日期", "转出报关单号"},
new String[]{"state", "batchNum", "serialNumber",
"sendDate", "rollInDate", "rollInCovorNO", "rollOutDate", "rollOutCovorNO"},
customsDeclaration, new TbRender() {
@Override
public String rend(Object col, Object target) {
if (col instanceof String && col.equals("state")) {
return target == null ? "" : CustomsDeclarationState.getDeclareStateName(Integer.parseInt(target.toString()));
}
return target == null ? "" : target + "";
}
});
List<String> HGDateDetail = messageQueryDao.checkHGDateDetailRemind(info[1]);
hasMessage = (HGDateDetail == null || HGDateDetail.size() <= 0) ? hasMessage : true;
String dateDetailTb = createHtmlTableString("供应商存在需要海关报关,明细信息见下表:",
new String[]{"申报提醒"},
null,
HGDateDetail, new TbRender() {
@Override
public String rend(Object col, Object target) {
if (col instanceof String && col.equals("state")) {
return target == null ? "" : CustomsDeclarationState.getDeclareStateName(Integer.parseInt(target.toString()));
}
return target == null ? "" : target + "";
}
});
List<String> coverExpiryMsgs = customsCoverLogic.getExpiryCustomsCover(info[1]);
hasMessage = (coverExpiryMsgs == null || coverExpiryMsgs.size() <= 0) ? hasMessage : true;
String coverExpiryTb = createHtmlTableString("存在将要过期的关封,明细信息见下表:",
new String[]{"关封有效期提醒"},
null,
coverExpiryMsgs, null);
return hasMessage
? wrapLi(companyInfo, new String[]{RecPart, CusDecTb, dateDetailTb, coverExpiryTb})
: "";
}
public void sendEmail(String[] to, String[] cc, String text) {
if (text == null || "".equals(text.trim())) {
return;
}
if ((to == null || to.length == 0) && (cc == null || cc.length == 0)) {
return;
}
//这个类主要是设置邮件
JavaMailSenderImpl senderImpl = new JavaMailSenderImpl();
// 设定mail server
senderImpl.setHost("smtp.gmail.com");
Properties prop = new Properties();
prop.put("mail.smtp.auth", "true"); // 将这个参数设为true,让服务器进行认证,认证用户名和密码是否正确
prop.put("mail.smtp.starttls.enable", "true");
prop.put("mail.smtp.timeout", " 25000");
String fromAddress = "noreply@ibestsoft.com";
senderImpl.setUsername(fromAddress); // 根据自己的情况,设置username
senderImpl.setPassword("ljgokyvhpdnkiciz"); // 根据自己的情况, 设置password
senderImpl.setJavaMailProperties(prop);
// 建立邮件消息
MimeMessage msg = senderImpl.createMimeMessage();
MimeMessageHelper helper = null;
try {
helper = new MimeMessageHelper(msg, true, "UTF-8");
helper.setFrom(fromAddress);
helper.setSubject(" 深加工结转平台预警通知 ");
helper.setText(text, true);
if (to != null && to.length != 0) {
helper.setTo(to);
}
if (cc != null && cc.length != 0) {
helper.setCc(cc);
}
} catch (MessagingException ex) {
Logger.getLogger(AutoSendWarnningEmail.class.getName()).log(Level.SEVERE, null, ex);
}
// 发送邮件
senderImpl.send(msg);
log.info(" 邮件发送成功.. ");
}
/**
* //---------暂停到0:00-----------
*/
private void currentThreadTime(Long currendTime) {
try {
Thread.sleep(currendTime);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
/**
* 计算暂停的秒数
*/
private Long calcSleepMilis(Date nowDate) {
//-------------计算暂停的秒数------------
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-M-dd HH:mm:ss", Locale.SIMPLIFIED_CHINESE);
Calendar lastDate = Calendar.getInstance();
lastDate.setTime(nowDate);
lastDate.set(Calendar.HOUR_OF_DAY, 24);
lastDate.set(Calendar.MINUTE, 0);
lastDate.set(Calendar.SECOND, 0);
String endDateTime = sdf.format(lastDate.getTime());
String startDateTime = sdf.format(nowDate);
Date endTime = null;
Date startTime = null;
try {
endTime = sdf.parse(endDateTime);
startTime = sdf.parse(startDateTime);
} catch (ParseException ex) {
Logger.getLogger(AutoSendWarnningEmail.class.getName()).log(Level.SEVERE, null, ex);
}
// System.out.println("startTime=" + startTime);
// System.out.println("endTime=" + endTime);
Long currendTime = endTime.getTime() - startTime.getTime();//最后暂停的秒数
log.info("自动发送邮件信息:----暂停 " + (currendTime / 1000) + "秒数");
//---------------------
return currendTime;
}
}
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package cn.com.bsw.btpls;
import cn.com.bsw.btpls.acluser.action.AclUserAction;
import cn.com.bsw.btpls.common.constant.CustomsDeclarationState;
import cn.com.bsw.btpls.customscover.dao.CustomsCoverDao;
import cn.com.bsw.btpls.customscover.entity.CustomsCoverHead;
import cn.com.bsw.btpls.customscover.logic.CustomsCoverLogic;
import cn.com.bsw.btpls.customsdeclaration.dao.CustomsDeclarationDao;
import cn.com.bsw.btpls.customsdeclaration.entity.CustomsDeclarationHead;
import cn.com.bsw.btpls.database.logic.DataBaseLogic;
import cn.com.bsw.btpls.indenture.dao.IndentureDao;
import cn.com.bsw.btpls.indenture.logic.IndentureLogic;
import cn.com.bsw.btpls.message.dao.MessageQueryDao;
import cn.com.bsw.btpls.systemconfigure.dao.SystemConfigureDao;
import cn.com.bsw.btpls.systemconfigure.entity.ApplyContact;
import cn.com.bsw.btpls.systemconfigure.entity.CustomsContact;
import cn.com.bsw.btpls.systemconfigure.entity.SystemConfigure;
import java.lang.reflect.InvocationTargetException;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;
import javax.ejb.EJB;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import org.apache.commons.beanutils.PropertyUtils;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
/**
* 自动对账
*
* @author lzj
*/
public class AutoSendWarnningEmail extends HttpServlet {
@EJB
private IndentureLogic indentureLogic = null;
@EJB
private IndentureDao indentureDao = null;
@EJB
private CustomsCoverDao customsCoverDao;
@EJB
private CustomsDeclarationDao customsDeclarationDao;
@EJB
private MessageQueryDao messageQueryDao;
private Logger log = Logger.getLogger(AutoSendWarnningEmail.class.getName());
@EJB
private AclUserAction userLogic = null;
@EJB
private DataBaseLogic dataBaseLogic = null;
@EJB
private SystemConfigureDao systemConfigureDao;
@EJB
private CustomsCoverLogic customsCoverLogic;
private SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
private DecimalFormat df = new DecimalFormat("#.00");
private ExecutorService executor;
/**
* 是否执行
*/
private boolean isExcuting = true;
@Override
public void destroy() {
isExcuting = false;
if (executor != null && !executor.isShutdown()) {
executor.shutdown();
}
System.out.println("自动发送邮件线程退出!");
Logger.getLogger("自动发送邮件线程退出!");
super.destroy();
}
@Override
public void init() throws ServletException {
super.init();
Logger.getLogger("正在初始化自动发送邮件线程!");
executor = Executors.newFixedThreadPool(10);//最多10个线程用于发送邮件(发送邮件等待时间比较长)
ProcessThread thread = new ProcessThread();
thread.setPriority(Thread.NORM_PRIORITY);
thread.start();
Logger.getLogger("初始化自动发送邮件线程结束!");
}
class MailSenderKH implements Runnable {
String[] customsEmail;
String khName;
String khCode;
String msg;
public MailSenderKH(String[] customsEmail, String khName, String khCode, String msg) {
this.customsEmail = customsEmail;
this.khName = khName;
this.khCode = khCode;
this.msg = msg;
}
public void run() {
try {
sendEmail(customsEmail, null,
msg);
log.info("信息:----自动发送邮件成功!转入方公司编码为:【" + khCode + "】的预警信息发送成功。");
} catch (Exception e) {
e.printStackTrace();
log.info("信息:----自动发送邮件出错!转入方公司编码为:【" + khCode + "】的预警信息发送失败。");
//若发送出错,继续
}
}
}
class MailSenderGYS implements Runnable {
String compantInfo;
List<String> tempAppls;
String msg;
public MailSenderGYS(String compantInfo, List<String> tempAppls, String msg) {
this.compantInfo = compantInfo;
this.tempAppls = tempAppls;
this.msg = msg;
}
public void run() {
try {
String companycode = compantInfo.split(",")[1];
sendEmail(tempAppls.toArray(new String[tempAppls.size()]), null,
msg);
log.info("信息:----自动发送邮件成功!转出方公司编码为:【" + companycode + "】的预警信息发送成功。");
} catch (Exception e) {
e.printStackTrace();
log.info("信息:----自动发送邮件出错!转出方公司编码为:【" + compantInfo.split(",")[1] + "】的预警信息发送失败。");
}
}
}
class ProcessThread extends Thread {
long currendTime = 0;
Date nowDate = null;
@Override
public void run() {
while (isExcuting) {
//----------获得服务器日期----------
nowDate = indentureDao.getNowTime();
try {
currendTime = calcSleepMilis(nowDate);
currentThreadTime(currendTime);
//以下是发送查询是否存在预警信息信息,并发送
List<ApplyContact> suppliers = systemConfigureDao.findApplyContactList(null);
List<CustomsContact> customers = systemConfigureDao.findAllData(CustomsContact.class.getName());
List<SystemConfigure> systemConfigures = systemConfigureDao.findAllData(SystemConfigure.class.getName());
//筛选出所有转入方email
List<String> customsEmail = new ArrayList<String>();
for (CustomsContact customsContact : customers) {
String email = customsContact.geteMail();
if (email != null && !"".equals(email.trim())) {
if (checkEmail(email)) {//筛选掉不合法的email
if (!customsEmail.contains(email)) {
customsEmail.add(email);
}
}
}
}
//筛选出转出方的企业和email
Map applEmail = new HashMap();
for (ApplyContact applyContact : suppliers) {
String email = applyContact.getContEMail();
if (email == null || "".equals(email.trim())) {
continue;
}
if (!checkEmail(email)) {//筛选掉不合法的email
continue;
}
String compantInfo = applyContact.getCompanyName() + "," + applyContact.getCompanyCode() + "," + applyContact.getKhName() + "," + applyContact.getKhCode();
if (applEmail.get(compantInfo) == null) {
List<String> emailList = new ArrayList<String>();
emailList.add(email);
applEmail.put(compantInfo, emailList);
} else {
List emailList = (List) applEmail.get(compantInfo);
if (!emailList.contains(email)) {
emailList.add(email);
}
}
}
//对每一个存在联系方式并且维护了email的供应商获取并发送预警信息,并把所有发给供应商的信息汇总,下面发送给转入方
for (Object temp : applEmail.keySet()) {
MailSenderGYS senderGYS = new MailSenderGYS((String) temp, ((List) applEmail.get(temp)), getMessagePerGYS((String) temp));
executor.submit(senderGYS);
}
//发送邮件到转入方
String khName = systemConfigures.get(0).getKhName();
String khCode = systemConfigures.get(0).getKhCode();
MailSenderKH senderKH = new MailSenderKH(customsEmail.toArray(new String[customsEmail.size()]), khName, khCode, getMessagePerKH(khName, khCode));
executor.submit(senderKH);
} catch (Exception ex) {
ex.printStackTrace();
log.info("信息:----自动发送邮件出错!");
}
}
}
}
public boolean checkEmail(String target) {
return Pattern.matches("\\w+@\\w+[.]\\w+", target);
}
private String toHtmlString(Object target) {
if (target == null) {
return "";
}
String temp = target + "";
if (target instanceof Double || target instanceof Float) {
temp = df.format(target);
}
if (target instanceof Date) {
temp = format.format(target);
}
temp = temp.replaceAll("&", "&");
temp = temp.replaceAll("<", "<");
temp = temp.replaceAll(">", ">");
temp = temp.replaceAll("\"", """);
return temp;
}
/**
* 拼接出一个Li标签中的一个table标签的字符串(当表格中的数据位空时返回空字符串)
*
* @param title 该分点的标题
* @param colNames 该表格的列名
* @param propNamesOrIndex 各列的属性名或者行为数组时的下标
* @param data 填充在表格中的数据
* @param render 填充时获取对应显示用的字符串
* @return
*/
private String createHtmlTableString(String title, String[] colNames, Object[] propNamesOrIndex, List data, TbRender render) {
if (data == null || data.size() <= 0) {
return "";
}
//拼接分点标题
String tableStr = "<li><span>" + title + "</span><p>";
tableStr += "<table>";
//拼接表格的列名
tableStr += "<tr>";
for (int i = 0; i < colNames.length; i++) {
tableStr += "<th>" + colNames[i] + "</th>";
}
tableStr += "</tr>";
//拼接表格的每行
for (Object row : data) {
tableStr += "<tr>";
if (row instanceof Object[]) {
Object[] tempRow = (Object[]) row;
for (int i = 0; i < colNames.length; i++) {
tableStr += "<td>";
if (render != null) {
if (propNamesOrIndex != null) {
Integer[] index = (Integer[]) propNamesOrIndex;
tableStr += toHtmlString(render.rend(i, tempRow[index[i]]));
} else {
tableStr += toHtmlString(render.rend(i, tempRow[i]));
}
} else {
if (propNamesOrIndex != null) {
Integer[] index = (Integer[]) propNamesOrIndex;
tableStr += toHtmlString(tempRow[index[i]]);
} else {
tableStr += toHtmlString(tempRow[i]);
}
}
tableStr += "</td>";
}
} else {
if (propNamesOrIndex != null) {
String[] propNames = (String[]) propNamesOrIndex;
for (String propName : propNames) {
tableStr += "<td>";
try {
if (render != null) {
tableStr += toHtmlString(render.rend(propName, PropertyUtils.getProperty(row, propName)));
} else {
tableStr += toHtmlString(PropertyUtils.getProperty(row, propName));
}
} catch (IllegalAccessException ex) {
Logger.getLogger(AutoSendWarnningEmail.class.getName()).log(Level.SEVERE, null, ex);
} catch (InvocationTargetException ex) {
Logger.getLogger(AutoSendWarnningEmail.class.getName()).log(Level.SEVERE, null, ex);
} catch (NoSuchMethodException ex) {
Logger.getLogger(AutoSendWarnningEmail.class.getName()).log(Level.SEVERE, null, ex);
}
tableStr += "</td>";
}
} else {//只有一列的情况下,直接传入字符串
tableStr += "<td>";
tableStr += toHtmlString(row);
tableStr += "</td>";
}
}
tableStr += "</tr>";
}
tableStr += "</table><br></li>";
return tableStr;
}
/**
* 把拼接出来的表格拼接都html的ul列表中
*
* @param customsName
* @param customsCode
* @param parts
* @return
*/
public String wrapLi(String customsName, String customsCode, String[] parts) {
String htmlString = "<html>"
+ "<head>"
+ "<style type=\"text/css\">"
+ "table{"
+ "background:#F6F9ED;"
+ "border: 1px solid #838B8B;"
+ "margin-left:20;"
+ "margin-top:20;"
+ "border-collapse:collapse;"
+ "}"
+ "td{"
+ "border: 1px solid #838B8B;"
+ "text-align:center;"
+ "padding:5px;"
+ "}"
+ "th{"
+ "background:#E0EEEE;"
+ "border: 1px solid #838B8B;"
+ "text-align:center;"
+ "padding:5px;"
+ "}"
+ "li{"
+ "/*border: 1px solid #838B8B;*/"
+ "margin-top:20;"
+ "padding:20;"
+ "}"
+ "div{"
+ "width:600;"
+ "}"
+ "span{"
+ ""
+ "}"
+ "</style>"
+ "</head>"
+ "<body>"
+ "尊敬的用户您好!" + customsName + "【" + customsCode + "】。<br>"
+ "<p><span>您有待处理的业务:</span><p>"
+ "<ul>";
for (String tb : parts) {
htmlString += tb;
}
htmlString += "</ul>"
+ "</body>"
+ "</html>";
return htmlString;
}
public abstract class TbRender {
public abstract String rend(Object col, Object target);
}
/**
* 把拼接出来的表格拼接都html的ul列表中
*
* @param customsName
* @param customsCode
* @param parts
* @return
*/
public String wrapLi(String companyInfo, String[] parts) {
String[] info = companyInfo.split(",");
String htmlString = "<html>"
+ "<head>"
+ "<style type=\"text/css\">"
+ "table{"
+ "background:#F6F9ED;"
+ "border: 1px solid #838B8B;"
+ "margin-left:20;"
+ "margin-top:20;"
+ "border-collapse:collapse;"
+ "}"
+ "td{"
+ "border: 1px solid #838B8B;"
+ "text-align:center;"
+ "padding:5px;"
+ "}"
+ "th{"
+ "background:#E0EEEE;"
+ "border: 1px solid #838B8B;"
+ "text-align:center;"
+ "padding:5px;"
+ "}"
+ "li{"
+ "/*border: 1px solid #838B8B;*/"
+ "margin-top:20;"
+ "padding:20;"
+ "}"
+ "div{"
+ "width:600;"
+ "}"
+ "span{"
+ ""
+ "}"
+ "</style>"
+ "</head>"
+ "<body>"
+ "尊敬的用户您好!" + info[0] + "【" + info[1] + "】,转入公司:" + info[2] + "【" + info[3] + "】。<br>"
+ "<p><span>您有待处理的业务:</span><p>"
+ "<ul>";
for (String tb : parts) {
htmlString += tb;
}
htmlString += "</ul>"
+ "</body>"
+ "</html>";
return htmlString;
}
private String getMessagePerKH(String customsName, String customsCode) {
boolean hasMessage = false;
List<CustomsCoverHead> coverHeadWait = customsCoverDao.remindKHCoverHeadWait();
hasMessage = (coverHeadWait == null || coverHeadWait.size() <= 0) ? hasMessage : true;
String coverTb = createHtmlTableString("办理转出关封存在需要办理转入关封的业务,明细信息见下表:",
new String[]{"关封号", "供应商名称", "开始日期", "截止日期"},
new String[]{"coverNO", "companyName", "startDate", "expiryDate"},
coverHeadWait, null);
List<Object[]> KHFormalIndenture = indentureDao.remindKHFormalIndenture();
hasMessage = (KHFormalIndenture == null || KHFormalIndenture.size() <= 0) ? hasMessage : true;
String IndentureTb = createHtmlTableString("收发货后存在需要办理报关的业务,明细信息见下表:",
new String[]{"转出方编码", "转出方名称", "关帐批次号", "发货日期", "截止报关日期", "离报关截止日期还剩天数"},
new Integer[]{5, 0, 1, 2, 3, 4},
KHFormalIndenture, null);
//加入供应商预警信息统计
List<String> reconciliations = indentureLogic.checkKHReconciliationTime();
hasMessage = (reconciliations == null || reconciliations.size() <= 0) ? hasMessage : true;
String recTb = createHtmlTableString("收发货对帐 : 收发货单存在需要及时对帐,明细信息见下表:",
new String[]{"对帐提醒"},
null,
reconciliations, null);
List<CustomsDeclarationHead> customsDeclaration = customsDeclarationDao.remindKHCustomsDeclaration();
hasMessage = (customsDeclaration == null || customsDeclaration.size() <= 0) ? hasMessage : true;
String CusDecTb = createHtmlTableString("转入报关后转出存在未办理报关,明细信息见下表:",
new String[]{"供应商编码", "供应商名称", "状态", "批次号", "流水号", "申请日期", "转入日期", "转入报关单号", "转出日期", "转出报关单号"},
new String[]{"companyCode", "companyName", "state", "batchNum", "serialNumber",
"sendDate", "rollInDate", "rollInCovorNO", "rollOutDate", "rollOutCovorNO"},
customsDeclaration, new TbRender() {
@Override
public String rend(Object col, Object target) {
if (col instanceof String && col.equals("state")) {
return target == null ? "" : CustomsDeclarationState.getDeclareStateName(Integer.parseInt(target.toString()));
}
return target == null ? "" : target + "";
}
});
List<String> HGDateDetail = messageQueryDao.checkHGDateDetailRemindForKH();
hasMessage = (HGDateDetail == null || HGDateDetail.size() <= 0) ? hasMessage : true;
String dateDetailTb = createHtmlTableString("供应商存在需要海关报关,明细信息见下表:",
new String[]{"申报提醒"},
null,
HGDateDetail, null);
List<String> coverExpiryMsgs = customsCoverLogic.getExpiryCustomsCover(null);
hasMessage = (coverExpiryMsgs == null || coverExpiryMsgs.size() <= 0) ? hasMessage : true;
String coverExpiryTb = createHtmlTableString("存在将要过期的关封,明细信息见下表:",
new String[]{"关封有效期提醒"},
null,
coverExpiryMsgs, null);
return hasMessage
? wrapLi(customsName, customsCode, new String[]{coverTb, IndentureTb, CusDecTb, dateDetailTb, recTb, coverExpiryTb})
: "";
}
private String getMessagePerGYS(String companyInfo) {
String[] info = companyInfo.split(",");
boolean hasMessage = false;
String temp = indentureLogic.checkGYSReconciliationTime(info[1]);
String RecPart = "";//对帐列表分点的字符串
if (!temp.equals("")) {
hasMessage = true;
RecPart += "<li>" + temp + "<p></li>";
}
List<CustomsDeclarationHead> customsDeclaration = customsDeclarationDao.remindGYSCustomsDeclaration(info[1]);
hasMessage = (customsDeclaration == null || customsDeclaration.size() <= 0) ? hasMessage : true;
String CusDecTb = createHtmlTableString("转入报关后转出存在未办理报关,明细信息见下表:",
new String[]{"状态", "批次号", "流水号", "申请日期", "转入日期", "转入报关单号", "转出日期", "转出报关单号"},
new String[]{"state", "batchNum", "serialNumber",
"sendDate", "rollInDate", "rollInCovorNO", "rollOutDate", "rollOutCovorNO"},
customsDeclaration, new TbRender() {
@Override
public String rend(Object col, Object target) {
if (col instanceof String && col.equals("state")) {
return target == null ? "" : CustomsDeclarationState.getDeclareStateName(Integer.parseInt(target.toString()));
}
return target == null ? "" : target + "";
}
});
List<String> HGDateDetail = messageQueryDao.checkHGDateDetailRemind(info[1]);
hasMessage = (HGDateDetail == null || HGDateDetail.size() <= 0) ? hasMessage : true;
String dateDetailTb = createHtmlTableString("供应商存在需要海关报关,明细信息见下表:",
new String[]{"申报提醒"},
null,
HGDateDetail, new TbRender() {
@Override
public String rend(Object col, Object target) {
if (col instanceof String && col.equals("state")) {
return target == null ? "" : CustomsDeclarationState.getDeclareStateName(Integer.parseInt(target.toString()));
}
return target == null ? "" : target + "";
}
});
List<String> coverExpiryMsgs = customsCoverLogic.getExpiryCustomsCover(info[1]);
hasMessage = (coverExpiryMsgs == null || coverExpiryMsgs.size() <= 0) ? hasMessage : true;
String coverExpiryTb = createHtmlTableString("存在将要过期的关封,明细信息见下表:",
new String[]{"关封有效期提醒"},
null,
coverExpiryMsgs, null);
return hasMessage
? wrapLi(companyInfo, new String[]{RecPart, CusDecTb, dateDetailTb, coverExpiryTb})
: "";
}
public void sendEmail(String[] to, String[] cc, String text) {
if (text == null || "".equals(text.trim())) {
return;
}
if ((to == null || to.length == 0) && (cc == null || cc.length == 0)) {
return;
}
//这个类主要是设置邮件
JavaMailSenderImpl senderImpl = new JavaMailSenderImpl();
// 设定mail server
senderImpl.setHost("smtp.gmail.com");
Properties prop = new Properties();
prop.put("mail.smtp.auth", "true"); // 将这个参数设为true,让服务器进行认证,认证用户名和密码是否正确
prop.put("mail.smtp.starttls.enable", "true");
prop.put("mail.smtp.timeout", " 25000");
String fromAddress = "noreply@ibestsoft.com";
senderImpl.setUsername(fromAddress); // 根据自己的情况,设置username
senderImpl.setPassword("ljgokyvhpdnkiciz"); // 根据自己的情况, 设置password
senderImpl.setJavaMailProperties(prop);
// 建立邮件消息
MimeMessage msg = senderImpl.createMimeMessage();
MimeMessageHelper helper = null;
try {
helper = new MimeMessageHelper(msg, true, "UTF-8");
helper.setFrom(fromAddress);
helper.setSubject(" 深加工结转平台预警通知 ");
helper.setText(text, true);
if (to != null && to.length != 0) {
helper.setTo(to);
}
if (cc != null && cc.length != 0) {
helper.setCc(cc);
}
} catch (MessagingException ex) {
Logger.getLogger(AutoSendWarnningEmail.class.getName()).log(Level.SEVERE, null, ex);
}
// 发送邮件
senderImpl.send(msg);
log.info(" 邮件发送成功.. ");
}
/**
* //---------暂停到0:00-----------
*/
private void currentThreadTime(Long currendTime) {
try {
Thread.sleep(currendTime);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
/**
* 计算暂停的秒数
*/
private Long calcSleepMilis(Date nowDate) {
//-------------计算暂停的秒数------------
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-M-dd HH:mm:ss", Locale.SIMPLIFIED_CHINESE);
Calendar lastDate = Calendar.getInstance();
lastDate.setTime(nowDate);
lastDate.set(Calendar.HOUR_OF_DAY, 24);
lastDate.set(Calendar.MINUTE, 0);
lastDate.set(Calendar.SECOND, 0);
String endDateTime = sdf.format(lastDate.getTime());
String startDateTime = sdf.format(nowDate);
Date endTime = null;
Date startTime = null;
try {
endTime = sdf.parse(endDateTime);
startTime = sdf.parse(startDateTime);
} catch (ParseException ex) {
Logger.getLogger(AutoSendWarnningEmail.class.getName()).log(Level.SEVERE, null, ex);
}
// System.out.println("startTime=" + startTime);
// System.out.println("endTime=" + endTime);
Long currendTime = endTime.getTime() - startTime.getTime();//最后暂停的秒数
log.info("自动发送邮件信息:----暂停 " + (currendTime / 1000) + "秒数");
//---------------------
return currendTime;
}
}