package com.espeed.reading.util; import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import java.io.UnsupportedEncodingException; import java.net.URL; import java.net.URLDecoder; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.regex.Pattern; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import net.sf.json.JSONObject; import org.apache.commons.lang.StringEscapeUtils; import org.apache.commons.lang.StringUtils; import com.espeed.ua.UserAgent; /** * * * @项目名称: 邮件跟踪系统 * @版权所有: 深圳市科飞时速网络技术有限公司(0755-88843776) * @技术支持: info@21gmail.com * @单元名称: 邮件跟踪工具类 * @开始时间: 2018-5-23 * @开发人员: 杨志钊 */ public class TrackUtil { public static void test(HttpServletRequest request, HttpServletResponse response) throws Exception { Thread.sleep(2000); String ip = NetworkUtil.getIpAddress(request); String toMail = request.getParameter("ywxMail"); System.out.println(ip); System.out.println(toMail); if (StringUtils.isNotEmpty(toMail)) { String uid = null; List<String> emails = new ArrayList<String>(); Cookie[] cookies = request.getCookies(); if (cookies != null && cookies.length > 0) { for (Cookie cookie : cookies) { if (ConstantUtil.USER_IDENTITY_COOKIE.equals(cookie .getName())) { uid = cookie.getValue(); } if (cookie.getName().startsWith( ConstantUtil.EMAIL_IDENTITY_COOKIE)) { if (cookie.getValue() != null && emailPattern.matcher(cookie.getValue()) .matches()) { emails.add(cookie.getValue()); } } } } // 设置cookie String serverDomain = request.getServerName(); int len = 0; if (!ipPattern.matcher(serverDomain).matches()) { String[] domains = serverDomain.split("\\."); len = domains.length; if (len > 2) { serverDomain = domains[len - 2] + "." + domains[len - 1]; } } Cookie cookie = new Cookie(ConstantUtil.USER_IDENTITY_COOKIE, uid); cookie.setMaxAge(ConstantUtil.HALF_CENTURY); cookie.setDomain(serverDomain); response.addCookie(cookie); len = emails.size(); for (int i = 0; i < len; i++) { cookie = new Cookie(ConstantUtil.EMAIL_IDENTITY_COOKIE + "_" + i, emails.get(i)); cookie.setMaxAge(ConstantUtil.HALF_CENTURY); cookie.setDomain(serverDomain); response.addCookie(cookie); } } } // 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待 private static ExecutorService fixedThreadPool = Executors .newFixedThreadPool(3); private static final String controlCentreUrl = ConfigPath .getControlCentreUrl(); // private static ExecutorService singleThreadExecutor = Executors // .newSingleThreadExecutor(); private static final Pattern ipPattern = Pattern.compile("[\\d\\.]*"); private static final Pattern emailPattern = Pattern.compile(ConfigPath .getEmailPattern()); private static final String secretkey = ConfigPath.getSecretKey(); /** 记录用户打开原邮件的行为 */ public static void recordOriginalMailInfo(HttpServletRequest request, HttpServletResponse response) { Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; int userId = 0; try { String ip = NetworkUtil.getIpAddress(request); if (ip != null && !ip.equalsIgnoreCase("unknown") && !ip.equalsIgnoreCase("null")) { String toMail = request.getParameter("to");// 点读地址 String mailUid = request.getParameter("mailuid");// 邮件唯一码 String loginId = request.getParameter("loginid");// 用户账号 String domain = request.getParameter("domain");// 用户域名 String mailId = request.getParameter("mailId"); String jsessionId = request.getSession().getId(); String poporimap = request.getParameter("poporimap");//null/0是pop,1是imap poporimap = poporimap == null ? "0" : poporimap.replace("3D", "").trim(); if (toMail == null || mailUid == null || domain == null) { System.err.println("参数缺失:toMail=" + toMail + ",mailUid=" + mailUid + ",loginId=" + loginId + ",domain=" + domain); return; } if (mailUid != null) { mailUid = URLDecoder.decode(mailUid, "UTF-8"); } if (toMail != null) { toMail = URLDecoder.decode(toMail, "UTF-8"); } if (loginId != null) { loginId = URLDecoder.decode(loginId, "UTF-8"); } if (domain != null) { domain = URLDecoder.decode(domain, "UTF-8"); } String uid = null; List<String> emails = new ArrayList<String>(); boolean cookieEnabled = true; String emailStr = ""; Cookie[] cookies = request.getCookies(); if (cookies != null && cookies.length > 0) { for (Cookie cookie : cookies) { if (ConstantUtil.USER_IDENTITY_COOKIE.equals(cookie .getName())) { uid = cookie.getValue(); } if (cookie.getName().startsWith( ConstantUtil.EMAIL_IDENTITY_COOKIE)) { if (cookie.getValue() != null && emailPattern.matcher(cookie.getValue()) .matches()) { emails.add(cookie.getValue()); emailStr = "," + cookie.getValue(); } } } } if (!emailStr.isEmpty()) { emailStr = emailStr.substring(1); } int ywxType = Integer.valueOf(request.getAttribute("ywxType") .toString()); Map<String, Object> userInfo = null; if (ywxType == 0) { userInfo = CentreDBUtil.getUserInfo(loginId, domain); if (!userInfo.get("code").equals(200)) { System.err.println("获取用户信息失败:" + userInfo.get("msg")); return; } } else { if (mailUid == null || mailUid.trim().isEmpty()) { System.err.println(toMail + "不存在mailUid"); return; } userInfo = WebmailDBUtil.getUserInfo(mailUid); if (!userInfo.get("code").equals(200)) { System.err.println("通过邮件id获取用户信息失败:" + userInfo.get("msg")); return; } } userId = Integer.valueOf(userInfo.get("userId").toString()); int companyId = Integer.valueOf(userInfo.get("companyId") .toString()); String title = null; Map<String, Object> mailInfo = null; if (ywxType == 0) { mailInfo = YxyDBUtil.getMailInfo(mailUid); if (!mailInfo.get("code").equals(200)) { System.err.println("获取邮件信息失败:" + mailInfo.get("msg")); // return; } } else { mailInfo = WebmailDBUtil.getMailInfo(mailUid); if (!mailInfo.get("code").equals(200)) { System.err.println("获取邮件信息失败:" + mailInfo.get("msg")); // return; } } if (mailInfo.containsKey("subject")) { title = String.valueOf(mailInfo.get("subject")); } if (title != null && title.contains("###")) { title = title.split("###")[0]; } conn = DBUtil.getConnection(); conn.setAutoCommit(false);// 开启事务 String sql = null; long count = 0L; String dbuid = null;// 邮箱在数据库中的第一条记录下的cookie标识 if (toMail != null && !toMail.trim().isEmpty()) { sql = "select identity from ts_customer_access where access_email = ? order by create_time ASC limit 1"; ps = conn.prepareStatement(sql); ps.setString(1, toMail); rs = ps.executeQuery(); if (rs.first()) { dbuid = rs.getString("identity"); } if (dbuid != null && !dbuid.equals(uid)) { uid = dbuid; } } // cookie里面没有UID则查该ip是否有浏览过,若有的话,则该用户的浏览器不支持cookie if (uid == null) { sql = "select identity,jsession_id from ts_customer_access where ip = ? order by create_time asc"; ps = conn.prepareStatement(sql); ps.setString(1, ip); rs = ps.executeQuery(); if (rs.first()) {// 有浏览过 cookieEnabled = false; uid = rs.getString("identity"); jsessionId = rs.getString("jsession_id"); sql = "select identity from ts_customer_email where email = ?"; ps = conn.prepareStatement(sql); ps.setString(1, toMail); rs = ps.executeQuery(); if (rs.first()) { // 若是数据库已经存在cookie唯一标示,而又不对应,则替换 // 在搜索引擎的爬虫下会造成数据混乱 // if (!uid.equals(rs.getString("identity"))) { // sql = // "update ts_customer_access set identity = ? , access_email = ? where identity = ?"; // ps = conn.prepareStatement(sql); // ps.setString(1, rs.getString("identity")); // ps.setString(2, toMail); // ps.setString(3, uid); // // ps.executeUpdate(); // // uid = rs.getString("identity"); // } } else { sql = "select count(*) from ts_customer_email where identity = ? and email = ?"; ps = conn.prepareStatement(sql); ps.setString(1, uid); ps.setString(2, toMail); rs = ps.executeQuery(); if (rs.first()) { count = rs.getLong(1); } if (count == 0L) { sql = "insert into ts_customer_email(identity,email,create_time) values(?,?,?)"; ps = conn.prepareStatement(sql); ps.setString(1, uid); ps.setString(2, toMail); ps.setString(3, DateFormat.getNowDate()); // 添加email ps.executeUpdate(); } } } // 没有浏览过 if (uid == null) { sql = "select identity from ts_customer_email where email = ?"; ps = conn.prepareStatement(sql); ps.setString(1, toMail); rs = ps.executeQuery(); if (rs.first()) { uid = rs.getString("identity"); } else { uid = UUID.randomUUID().toString(); sql = "insert into ts_customer(identity,type,create_time) values(?,?,?)"; ps = conn.prepareStatement(sql); ps.setString(1, uid); ps.setInt(2, 1);// 客户类型,0:路人、1:已存在客户 ps.setString(3, DateFormat.getNowDate()); // 添加客户 ps.executeUpdate(); sql = "select count(*) from ts_customer_email where identity = ? and email = ?"; ps = conn.prepareStatement(sql); ps.setString(1, uid); ps.setString(2, toMail); rs = ps.executeQuery(); if (rs.first()) { count = rs.getLong(1); } if (count == 0L) { sql = "insert into ts_customer_email(identity,email,create_time) values(?,?,?)"; ps = conn.prepareStatement(sql); ps.setString(1, uid); ps.setString(2, toMail); ps.setString(3, DateFormat.getNowDate()); // 添加email ps.executeUpdate(); } } } } else { // sql = // "select identity from ts_customer_email where email = ?"; // ps = conn.prepareStatement(sql); // ps.setString(1, toMail); // String identity = null; // rs = ps.executeQuery(); // if (rs.first()) { // identity = rs.getString("identity"); // } // 在搜索引擎的爬虫下会造成数据混乱 // 若是已经存在cookie唯一标示,而数据库又有该邮箱的cookie,则替换 // if (identity != null && !uid.equals(identity)) { // sql = // "update ts_customer_access set identity = ? , access_email = ? where identity = ?"; // ps = conn.prepareStatement(sql); // ps.setString(1, identity); // ps.setString(2, toMail); // ps.setString(3, uid); // // ps.executeUpdate(); // // uid = identity; // } // 浏览器没有该客户邮箱且数据没有保存,则保存 if (!emails.contains(toMail)) { sql = "select count(*) from ts_customer_email where identity = ? and email = ?"; ps = conn.prepareStatement(sql); ps.setString(1, uid); ps.setString(2, toMail); rs = ps.executeQuery(); if (rs.first()) { count = rs.getLong(1); } if (count == 0L) { sql = "insert into ts_customer_email(identity,email,create_time) values(?,?,?)"; ps = conn.prepareStatement(sql); ps.setString(1, uid); ps.setString(2, toMail); ps.setString(3, DateFormat.getNowDate()); // 添加email ps.executeUpdate(); } } } if (!emails.contains(toMail)) { emails.add(toMail); } // 数据组装 String agentString = request.getHeader("User-Agent"); String accessUrl = request.getHeader("Referer"); String accessDomain = null; if (accessUrl != null) { try { accessDomain = new URL(accessUrl).getHost(); } catch (Exception e) { System.err.println("accessUrl域名解析失败:" + e.getClass().getName() + (e.getMessage() == null ? "" : ("->" + e .getMessage()))); } if (request.getQueryString() != null) { accessUrl += "?" + request.getQueryString(); } } String language = request.getLocale().getLanguage(); if (request.getLocale().getCountry() != null && !request.getLocale().getCountry().trim().isEmpty()) { language += "-" + request.getLocale().getCountry(); } // 解析ip String url = controlCentreUrl + "/webservice/ip"; Map<String, Object> params = new HashMap<String, Object>(); params.put("ip", ip); String continent = null; String country = null; String province = null; String city = null; String address = null; String netProvider = null; Map<String, Object> result = HttpUtil.doGet(url, params); if (result.get("code").equals(200)) { Object data = result.get("data"); JSONObject json = JSONObject.fromObject(data); if (json.getInt("code") == 200) { json = JSONObject.fromObject(json.get("result")); netProvider = json.getString("isp"); continent = json.getString("land"); country = json.getString("country"); province = json.getString("prov"); city = json.getString("city"); address = json.getString("dist"); } else { System.err.println("ip解析失败:" + json.get("result")); } } else { System.err.println("ip解析失败:" + result.get("msg")); } UserAgent userAgent = UserAgent .parseUserAgentString(agentString); if ((accessUrl == null || accessUrl.trim().isEmpty()) || (mailUid == null || mailUid.trim().isEmpty()) || (toMail == null || toMail.trim().isEmpty())) { // 只要有一个为空就放弃添加 System.err.println("值缺失:accessUrl=" + accessUrl + ",mailUid=" + mailUid + ",toMail=" + toMail); // return; } if (toMail != null && !toMail.trim().isEmpty()) { if (!emailPattern.matcher(toMail.trim().toLowerCase()) .matches()) { // 邮箱格式错误就放弃添加 System.err.println("邮箱格式错误:" + toMail); return; } } // 添加浏览记录 sql = "insert into ts_customer_access(identity,user_id,company_id,mail_uid,title,from_url,from_domain,access_url,access_domain,ip,jsession_id,continent,country,province,city,address,device_type,browser_name,language,screen_x,screen_y,net_provider,os,search_word,user_agent,cookie_enable,access_time,access_email,res_type,create_time,template_id,customer_id,from_type,count_id,status,is_imap) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; ps = conn.prepareStatement(sql); ps.setString(1, uid);// cookie唯一标示 ps.setInt(2, userId);// 用户id ps.setInt(3, companyId);// 企业id ps.setString(4, mailUid);// 邮件唯一标示 ps.setString(5, title);// 来源标题 ps.setString(6, null);// 来源url ps.setString(7, null);// 来源域名 ps.setString(8, accessUrl);// 受访问url ps.setString(9, accessDomain);// 受访问域名 ps.setString(10, ip);// 客户端ip ps.setString(11, jsessionId);// 回话id ps.setString(12, continent);// 访问者所属洲 ps.setString(13, country);// 访问者所属国际 ps.setString(14, province);// //访问者所属省份 ps.setString(15, city);// //访问者所属城市 ps.setString(16, address);// //访问者所属详细地址 ps.setInt(17, TrackUtil.getDeviceType(userAgent));// 设备类型 ps.setString(18, userAgent.getBrowser().getName());// 浏览器名称 ps.setString(19, language);// 浏览器设置的语言 ps.setInt(20, 0);// 设备宽度 ps.setInt(21, 0);// 设备高度 ps.setString(22, netProvider);// 网络接入商 ps.setString(23, userAgent.getOperatingSystem().getName());// 操作系统名称 ps.setString(24, null);// 搜索词 ps.setString(25, agentString);// 浏览器ua ps.setInt(26, cookieEnabled ? 1 : 0);// 是否支持cookie,1支持、0不支持 ps.setInt(27, 0);// 访问时长,单位毫秒 ps.setString(28, toMail);// 客户邮箱 ps.setInt(29, ywxType);// 受访问资源类型,0营销邮邮件、1营销邮邮件HTML页面、2易外销用户站点、3营销邮邮件里需要跟踪的超链、4营销邮邮件HTML页面里需要跟踪的超链、5易外销邮件、6易外销邮件里需要跟踪的超链、7询盘 ps.setString(30, DateFormat.getNowDate());// 创建时间 ps.setInt(31, 0);// 模板id ps.setInt(32, WebmailDBUtil.getCustomerId(userId, toMail));// 客户id ps.setInt(33, 3);// 来源类别,-1无来源url、0:外链、1社交、2搜索、3邮件 ps.setLong(34, 0L);// 统计id ps.setInt(35, 1);// 状态,0删除、1正常 ps.setInt(36, Integer.valueOf(poporimap));// 是否是imap邮件,0否、1是 // 提交添加 ps.executeUpdate(); // 获取自动生成的id rs = ps.getGeneratedKeys(); long id = 0L; if (rs.first()) { id = rs.getLong(1); } sql = "select id,create_time from ts_customer_access where id != ? and identity = ? and user_id = ? and company_id = ? and to_days(create_time) = to_days(now()) order by create_time desc"; ps = conn.prepareStatement(sql); ps.setLong(1, id); ps.setString(2, uid); ps.setInt(3, userId); ps.setInt(4, companyId); // 有上一条记录则修改上一条记录的访问时长 rs = ps.executeQuery(); if (rs.first()) { long milliSeconds = DateFormat.milliSeconds( rs.getString("create_time"), DateFormat.getNowDate()); if (milliSeconds < (1000 * 60 * 60 * 2)) {// 当天前后两个请求大于2个小时的丢掉 sql = "update ts_customer_access set access_time = ? where id = ?"; ps = conn.prepareStatement(sql); ps.setLong(1, milliSeconds); ps.setLong(2, rs.getLong("id")); // 修改上一个请求的访问时长 ps.executeUpdate(); } } // 修改为已存在客户 // sql = "update ts_customer set type = ? where identity = ?"; // ps = conn.prepareStatement(sql); // ps.setInt(1, 1);// 客户类型,0:路人、1:已存在客户 // ps.setString(2, uid); // // 修改客户 // ps.executeUpdate(); // 设置cookie String serverDomain = request.getServerName(); int len = 0; if (!ipPattern.matcher(serverDomain).matches()) { String[] domains = serverDomain.split("\\."); len = domains.length; if (len > 2) { serverDomain = domains[len - 2] + "." + domains[len - 1]; } } Cookie cookie = new Cookie(ConstantUtil.USER_IDENTITY_COOKIE, uid); cookie.setMaxAge(ConstantUtil.HALF_CENTURY); cookie.setDomain(serverDomain); response.addCookie(cookie); len = emails.size(); for (int i = 0; i < len; i++) { cookie = new Cookie(ConstantUtil.EMAIL_IDENTITY_COOKIE + "_" + i, emails.get(i)); cookie.setMaxAge(ConstantUtil.HALF_CENTURY); cookie.setDomain(serverDomain); response.addCookie(cookie); } // 若不是在shenyingshejiao.net域名下,则要把cookie设置到该域名下 if (!request.getServerName().contains( ConfigPath.getClickDomain())) { response.sendRedirect(ConfigPath.getClickUrl() + "/cookieSetter.jsp?jsessionId=" + jsessionId + "&identity=" + uid + "&emails=" + emailStr); } // try的最后提交事务 conn.commit(); } else { System.err.println("无法获取ip"); } } catch (Exception e) { if (conn != null) { try { // 回滚事务 conn.rollback(); } catch (SQLException ex) { ex.printStackTrace(); } } e.printStackTrace(); LogUtil.saveInfoLog(request.getAttribute("ywxType") + "/" + userId, e); } finally { DBUtil.close(rs, ps, conn); } } /** 记录用户打开原邮件里的超链接的行为 */ public static void recordFromOriginalMailInfo(JSONObject param, List<String> emails) { Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; int ywxType = Integer.valueOf(param.getString("ywxType") .toString().replace("3D", "")); Integer userId2 = 0; Integer companyId2 = 0; if (ywxType == 9) {//9(sale100.com独立)营销邮邮件里需要跟踪的超链 ywxType = 3; Map<String, Object> userInfo = CentreDBUtil.getUserInfo(param.getString("ywxUid"), param.getString("ywxCid")); if (!userInfo.get("code").equals(200)) { System.err.println("获取用户信息失败:" + userInfo.get("msg")); return; } userId2 = Integer.valueOf(userInfo.get("userId").toString()); companyId2 = Integer.valueOf(userInfo.get("companyId").toString()); } else { userId2 = Integer .valueOf(param.getString("ywxUid") == null ? "0" : param.getString("ywxUid").replace("3D", "")); companyId2 = Integer.valueOf(param.getString("ywxCid") == null ? "0" : param.getString("ywxCid").replace("3D", "")); } final Integer userId = userId2; final Integer companyId = companyId2; try { String ip = param.getString("ip"); if (ip != null && !ip.equalsIgnoreCase("unknown") && !ip.equalsIgnoreCase("null")) { if (!param.containsKey("ywxMail")) { param.put("ywxMail", ""); } if (!param.containsKey("ywxMid")) { param.put("ywxMid", ""); } if (!param.containsKey("ywxX")) { param.put("ywxX", ""); } if (!param.containsKey("ywxH")) { param.put("ywxH", ""); } if (!param.containsKey("poporimap")) { param.put("poporimap", "0"); } if (!param.containsKey("ywxTitle")) { param.put("ywxTitle", ""); } if (!param.containsKey("ywxTo")) { param.put("ywxTo", ""); } final String toMail = (param.getString("ywxMail") != null && param.getString("ywxMail").startsWith("3D")) ? URLDecoder.decode(param.getString("ywxMail").replaceFirst("3D", ""), "UTF-8") : URLDecoder.decode(param.getString("ywxMail"), "UTF-8");// 点读地址 final String mailUid = (param.getString("ywxMid") != null && param.getString("ywxMid").startsWith("3D")) ? URLDecoder.decode(param.getString("ywxMid").replaceFirst("3D", ""), "UTF-8") : URLDecoder.decode(param.getString("ywxMid"), "UTF-8");// 邮件唯一码 Boolean cookieEnabled = Boolean.valueOf(param.getString( "ywxCookie").replace("3D", "")); Integer ywxX = Integer .valueOf(param.getString("ywxX") == null ? "0" : param.getString("ywxX") .replace("3D", "")); Integer ywxH = Integer .valueOf(param.getString("ywxH") == null ? "0" : param.getString("ywxH") .replace("3D", "")); String poporimap = param.getString("poporimap");//null/0是pop,1是imap poporimap = poporimap == null ? "0" : poporimap.replace("3D", "").trim(); String jsessionId = param.getString("jsessionId"); if (StringUtils.isEmpty(toMail) || StringUtils.isEmpty(mailUid) || userId == null || companyId == null || cookieEnabled == null || ywxX == null || ywxH == null) { System.err.println("参数缺失"); return; } Map<String, Object> mailInfo = null; String title = (param.getString("ywxTitle") != null && param.getString("ywxTitle").startsWith("3D")) ? param.getString("ywxTitle").replaceFirst("3D", "") : param.getString("ywxTitle"); if (title == null || title.trim().isEmpty() || title.equals("null")) { if (ywxType == 3) { mailInfo = YxyDBUtil.getMailInfo(mailUid); if (!mailInfo.get("code").equals(200)) { System.err.println("获取邮件信息失败:" + mailInfo.get("msg")); // return; } } else { mailInfo = WebmailDBUtil.getMailInfo(mailUid); if (!mailInfo.get("code").equals(200)) { System.err.println("获取邮件信息失败:" + mailInfo.get("msg")); // return; } } if (mailInfo.containsKey("subject")) { title = String.valueOf(mailInfo.get("subject")); } if (title != null && title.contains("###")) { title = title.split("###")[0]; } } String uid = null; if (param.containsKey("uid")) { uid = param.getString("uid"); } conn = DBUtil.getConnection(); conn.setAutoCommit(false);// 开启事务 String sql = null; long count = 0L; String dbuid = null;// 邮箱在数据库中的第一条记录下的cookie标识 if (toMail != null && !toMail.trim().isEmpty()) { sql = "select identity from ts_customer_access where access_email = ? order by create_time ASC limit 1"; ps = conn.prepareStatement(sql); ps.setString(1, toMail); rs = ps.executeQuery(); if (rs.first()) { dbuid = rs.getString("identity"); } if (dbuid != null && !dbuid.equals(uid)) { uid = dbuid; } } // cookie里面没有UID则查该ip是否有浏览过,若有的话,则该用户的浏览器不支持cookie if (uid == null) { if (!cookieEnabled) {// 浏览器不支持cookie sql = "select identity,jsession_id from ts_customer_access where ip = ? order by create_time asc"; ps = conn.prepareStatement(sql); ps.setString(1, ip); rs = ps.executeQuery(); if (rs.first()) {// 有浏览过 cookieEnabled = false; uid = rs.getString("identity"); jsessionId = rs.getString("jsession_id"); sql = "select identity from ts_customer_email where email = ?"; ps = conn.prepareStatement(sql); ps.setString(1, toMail); rs = ps.executeQuery(); if (rs.first()) { // 若是数据库已经存在cookie唯一标示,而又不对应,则替换 // 在搜索引擎的爬虫下会造成数据混乱 // if (!uid.equals(rs.getString("identity"))) { // sql = // "update ts_customer_access set identity = ? , access_email = ? where identity = ?"; // ps = conn.prepareStatement(sql); // ps.setString(1, rs.getString("identity")); // ps.setString(2, toMail); // ps.setString(3, uid); // // ps.executeUpdate(); // // uid = rs.getString("identity"); // } } else { sql = "select count(*) from ts_customer_email where identity = ? and email = ?"; ps = conn.prepareStatement(sql); ps.setString(1, uid); ps.setString(2, toMail); rs = ps.executeQuery(); if (rs.first()) { count = rs.getLong(1); } if (count == 0L) { sql = "insert into ts_customer_email(identity,email,create_time) values(?,?,?)"; ps = conn.prepareStatement(sql); ps.setString(1, uid); ps.setString(2, toMail); ps.setString(3, DateFormat.getNowDate()); // 添加email ps.executeUpdate(); } } } } // 没有浏览过 if (uid == null) { sql = "select identity from ts_customer_email where email = ?"; ps = conn.prepareStatement(sql); ps.setString(1, toMail); rs = ps.executeQuery(); if (rs.first()) { uid = rs.getString("identity"); } else { uid = UUID.randomUUID().toString(); } sql = "insert into ts_customer(identity,type,create_time) values(?,?,?)"; ps = conn.prepareStatement(sql); ps.setString(1, uid); ps.setInt(2, 1);// 客户类型,0:路人、1:已存在客户 ps.setString(3, DateFormat.getNowDate()); // 添加客户 ps.executeUpdate(); sql = "select count(*) from ts_customer_email where identity = ? and email = ?"; ps = conn.prepareStatement(sql); ps.setString(1, uid); ps.setString(2, toMail); rs = ps.executeQuery(); if (rs.first()) { count = rs.getLong(1); } if (count == 0L) { sql = "insert into ts_customer_email(identity,email,create_time) values(?,?,?)"; ps = conn.prepareStatement(sql); ps.setString(1, uid); ps.setString(2, toMail); ps.setString(3, DateFormat.getNowDate()); // 添加email ps.executeUpdate(); } } } else { // sql = // "select identity from ts_customer_email where email = ?"; // ps = conn.prepareStatement(sql); // ps.setString(1, toMail); // String identity = null; // rs = ps.executeQuery(); // if (rs.first()) { // identity = rs.getString("identity"); // } // // 若是已经存在cookie唯一标示,而数据库又有该邮箱的cookie,则替换 // 在搜索引擎的爬虫下会造成数据混乱 // if (identity != null && !uid.equals(identity)) { // sql = // "update ts_customer_access set identity = ? , access_email = ? where identity = ?"; // ps = conn.prepareStatement(sql); // ps.setString(1, identity); // ps.setString(2, toMail); // ps.setString(3, uid); // // ps.executeUpdate(); // // uid = identity; // } // 浏览器没有该客户邮箱且数据没有保存,则保存 if (!emails.contains(toMail)) { sql = "select count(*) from ts_customer_email where identity = ? and email = ?"; ps = conn.prepareStatement(sql); ps.setString(1, uid); ps.setString(2, toMail); rs = ps.executeQuery(); if (rs.first()) { count = rs.getLong(1); } if (count == 0L) { sql = "insert into ts_customer_email(identity,email,create_time) values(?,?,?)"; ps = conn.prepareStatement(sql); ps.setString(1, uid); ps.setString(2, toMail); ps.setString(3, DateFormat.getNowDate()); // 添加email ps.executeUpdate(); } } } if (!emails.contains(toMail)) { emails.add(toMail); } // 数据组装 String agentString = param.getString("agentString"); String referer = param.getString("referer"); String fromDomain = null; if (referer != null && !referer.trim().isEmpty()) { try { referer = URLDecoder.decode(referer, "UTF-8"); fromDomain = new URL(referer).getHost(); } catch (Exception e) { System.err.println("referer域名解析失败:" + e.getClass().getName() + (e.getMessage() == null ? "" : ("->" + e .getMessage()))); } } String language = param.getString("language"); String country2 = param.getString("country"); if (country2 != null && !country2.trim().isEmpty()) { language += "-" + country2; } String accessUrl = (param.getString("ywxTo") != null && param.getString("ywxTo").startsWith("3D")) ? param.getString("ywxTo").replaceFirst("3D", "") : param.getString("ywxTo"); // final String accessUrl2 = accessUrl; String accessDomain = null; if (accessUrl != null) { try { accessUrl = URLDecoder.decode(accessUrl, "UTF-8"); accessDomain = new URL(accessUrl).getHost(); } catch (Exception e) { System.err.println("ywxTo域名解析失败:" + e.getClass().getName() + (e.getMessage() == null ? "" : ("->" + e .getMessage()))); } } // 解析ip String url = controlCentreUrl + "/webservice/ip"; Map<String, Object> params = new HashMap<String, Object>(); params.put("ip", ip); String continent = null; String country = null; String province = null; String city = null; String address = null; String netProvider = null; Map<String, Object> result = HttpUtil.doGet(url, params); if (result.get("code").equals(200)) { Object data = result.get("data"); JSONObject json = JSONObject.fromObject(data); if (json.getInt("code") == 200) { json = JSONObject.fromObject(json.get("result")); netProvider = json.getString("isp"); continent = json.getString("land"); country = json.getString("country"); province = json.getString("prov"); city = json.getString("city"); address = json.getString("dist"); } else { System.err.println("ip解析失败:" + json.get("result")); } } else { System.err.println("ip解析失败:" + result.get("msg")); } UserAgent userAgent = UserAgent .parseUserAgentString(agentString); if ((accessUrl == null || accessUrl.trim().isEmpty()) || (mailUid == null || mailUid.trim().isEmpty()) || (toMail == null || toMail.trim().isEmpty())) { // 只要有一个为空就放弃添加 return; } if (toMail != null && !toMail.trim().isEmpty()) { if (!emailPattern.matcher(toMail.trim().toLowerCase()) .matches()) { // 邮箱格式错误就放弃添加 return; } } // 添加浏览记录 sql = "insert into ts_customer_access(identity,user_id,company_id,mail_uid,title,from_url,from_domain,access_url,access_domain,ip,jsession_id,continent,country,province,city,address,device_type,browser_name,language,screen_x,screen_y,net_provider,os,search_word,user_agent,cookie_enable,access_time,access_email,res_type,create_time,template_id,customer_id,from_type,count_id,status,is_imap) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; ps = conn.prepareStatement(sql); ps.setString(1, uid);// cookie唯一标示 ps.setInt(2, userId);// 用户id ps.setInt(3, companyId);// 企业id ps.setString(4, mailUid);// 邮件唯一标示 ps.setString(5, title);// 来源标题 ps.setString(6, referer);// 来源url ps.setString(7, fromDomain);// 来源域名 ps.setString(8, accessUrl);// 受访问url ps.setString(9, accessDomain);// 受访问域名 ps.setString(10, ip);// 客户端ip ps.setString(11, jsessionId);// 回话id ps.setString(12, continent);// 访问者所属洲 ps.setString(13, country);// 访问者所属国际 ps.setString(14, province);// //访问者所属省份 ps.setString(15, city);// //访问者所属城市 ps.setString(16, address);// //访问者所属详细地址 ps.setInt(17, TrackUtil.getDeviceType(userAgent));// 设备类型 ps.setString(18, userAgent.getBrowser().getName());// 浏览器名称 ps.setString(19, language);// 浏览器设置的语言 ps.setInt(20, ywxX);// 设备宽度 ps.setInt(21, ywxH);// 设备高度 ps.setString(22, netProvider);// 网络接入商 ps.setString(23, userAgent.getOperatingSystem().getName());// 操作系统名称 ps.setString(24, TrackUtil.getSearchWord(referer));// 搜索词 ps.setString(25, agentString);// 浏览器ua ps.setInt(26, cookieEnabled ? 1 : 0);// 是否支持cookie,1支持、0不支持 ps.setInt(27, 0);// 访问时长,单位毫秒 ps.setString(28, toMail);// 客户邮箱 ps.setInt(29, ywxType);// 受访问资源类型,0营销邮邮件、1营销邮邮件HTML页面、2易外销用户站点、3营销邮邮件里需要跟踪的超链、4营销邮邮件HTML页面里需要跟踪的超链、5易外销邮件、6易外销邮件里需要跟踪的超链、7询盘 ps.setString(30, DateFormat.getNowDate());// 创建时间 ps.setInt(31, 0);// 模板id ps.setInt(32, WebmailDBUtil.getCustomerId(userId, toMail));// 客户id ps.setInt(33, 3);// 来源类别,-1无来源url、0:外链、1社交、2搜索、3邮件 ps.setLong(34, 0L);// 统计id ps.setInt(35, 1);// 状态,0删除、1正常 ps.setInt(36, Integer.valueOf(poporimap));// 是否是imap邮件,0否、1是 // 提交添加 ps.executeUpdate(); // 获取自动生成的id rs = ps.getGeneratedKeys(); long id = 0L; if (rs.first()) { id = rs.getLong(1); } // final long aid = id; sql = "select id,create_time from ts_customer_access where id != ? and identity = ? and user_id = ? and company_id = ? and to_days(create_time) = to_days(now()) order by create_time desc"; ps = conn.prepareStatement(sql); ps.setLong(1, id); ps.setString(2, uid); ps.setInt(3, userId); ps.setInt(4, companyId); // 有上一条记录则修改上一条记录的访问时长 rs = ps.executeQuery(); if (rs.first()) { long milliSeconds = DateFormat.milliSeconds( rs.getString("create_time"), DateFormat.getNowDate()); if (milliSeconds < (1000 * 60 * 60 * 2)) {// 当天前后两个请求大于2个小时的丢掉 sql = "update ts_customer_access set access_time = ? where id = ?"; ps = conn.prepareStatement(sql); ps.setLong(1, milliSeconds); ps.setLong(2, rs.getLong("id")); // 修改上一个请求的访问时长 ps.executeUpdate(); } } final int recordType = ywxType; final long recordId = id; final String recordEmail = toMail; final String recordLink = (accessUrl == null ? null : URLDecoder.decode(accessUrl, "UTF-8")); final int recordUserId = userId; // 点击超链接时异步添加消息提醒:3营销邮邮件里需要跟踪的超链、6易外销邮件里需要跟踪的超链 if (recordLink != null && !recordLink.trim().isEmpty() && recordEmail != null && !recordEmail.trim().isEmpty() && Arrays.asList(3, 6).contains(recordType)) { fixedThreadPool.execute(new Runnable() { public void run() { System.out.println("开始添加邮件里超链点击消息提醒和统计..."); if (mailUid != null && !mailUid.trim().isEmpty() && recordType == 6) { System.out.println("开始添加邮件里超链点击统计..."); Connection conn3 = null; PreparedStatement ps3 = null; ResultSet rs3 = null; try { int tryCount = 0; conn3 = DBUtil.getConnection(); String sql2 = "select count(*) from ts_customer_access where res_type = 6 and access_url = ? and access_email = ? and user_id = ? and company_id = ? and mail_uid = ?"; ps3 = conn3.prepareStatement(sql2); ps3.setObject(1, recordLink); ps3.setObject(2, recordEmail); ps3.setObject(3, userId); ps3.setObject(4, companyId); ps3.setObject(5, mailUid); int cou = 0; rs3 = ps3.executeQuery(); if (rs3.first()) { cou = rs3.getInt(1); } if (cou <= 1) {//超过1条记录则不统计 Connection conn2 = null; PreparedStatement ps2 = null; ResultSet rs2 = null; while (conn2 == null && tryCount < 3) { tryCount++; try { conn2 = WebmailDBUtil.getConnection(); } catch (Exception e) { e.printStackTrace(); try { Thread.sleep(5000); } catch (InterruptedException ex) { ex.printStackTrace(); } } } sql2 = "select id from attr_link_count where mail_uid = ?"; ps2 = conn2.prepareStatement(sql2); ps2.setObject(1, mailUid); rs2 = ps2.executeQuery(); if (rs2.first()) {//已存在 cou = rs2.getInt(1); rs2.close(); ps2.close(); sql2 = "update attr_link_count set link_count = link_count + 1 where id = ?"; ps2 = conn2.prepareStatement(sql2); ps2.setObject(1, cou); ps2.executeUpdate(); } else {//未存在 rs2.close(); ps2.close(); sql2 = "insert into attr_link_count(mail_uid,file_count,link_count) values(?,?,?)"; ps2 = conn2.prepareStatement(sql2); ps2.setObject(1, mailUid); ps2.setObject(2, 0); ps2.setObject(3, 1); ps2.executeUpdate(); } //conn2.commit(); WebmailDBUtil.close(rs2, ps2, conn2); } } catch (SQLException ex) { ex.printStackTrace(); } finally { DBUtil.close(rs3, ps3, conn3); } } String title = null; Map<String, Object> mailInfo = null; if (recordType == 3) { mailInfo = YxyDBUtil.getMailInfo(mailUid); if (!mailInfo.get("code").equals(200)) { System.err.println("获取邮件信息失败:" + mailInfo.get("msg")); // return; } } else { mailInfo = WebmailDBUtil.getMailInfo(mailUid); if (!mailInfo.get("code").equals(200)) { System.err.println("获取邮件信息失败:" + mailInfo.get("msg")); // return; } } if (mailInfo.containsKey("subject")) { title = String.valueOf(mailInfo.get("subject")); } if (title != null && title.contains("###")) { title = title.split("###")[0]; } if (title == null || title.trim().isEmpty()) { title = "未知"; } Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; try { //一个封邮件里的一个超链接一天提醒一次 // 《xx》邮箱点开了您邮件/模板《xx》里的超链接《xx》 conn = WebmailDBUtil.getConnection(); String sql = "select id from sys_user_remind where to_days(remind_time) = to_days(now()) and remind_content like '《" + recordEmail.trim() + "》%点开了您邮件《" + title.trim() + "》%超链接《" + recordLink.trim() + "》%' and remind_userid = " + recordUserId; ps = conn.prepareStatement(sql); rs = ps.executeQuery(); int id = 0; if (rs.first()) { id = rs.getInt("id"); System.out.println("已有消息id:" + id); } if (id == 0) { String content = "《"+recordEmail.trim()+"》邮箱点开了您邮件《"+title.trim()+"》里的超链接《"+recordLink.trim()+"》,请前往追踪统计查看!"; sql = "insert into sys_user_remind(remind_userid,remind_type,remind_status,remind_time,remind_content,target_id,is_read) values(?,?,?,?,?,?,?)"; ps = conn.prepareStatement(sql); ps.setObject(1, recordUserId); ps.setObject(2, 21); ps.setObject(3, 0); ps.setObject(4, DateFormat.getNowDate()); ps.setObject(5, content); ps.setObject(6, recordId); ps.setObject(7, 0); ps.executeUpdate(); System.out.println("消息提醒添加完成"); } } catch (Exception e) { e.printStackTrace(); } finally { WebmailDBUtil.close(rs, ps, conn); } } }); } // 异步统计邮件里的超链 // singleThreadExecutor.execute(new Runnable() { // // public void run() { // // TrackUtil.countLink(userId, companyId, mailUid, // accessUrl2, toMail, aid); // } // }); // try的最后提交事务 conn.commit(); } else { System.err.println("无法获取ip"); } } catch (Exception e) { if (conn != null) { try { // 回滚事务 conn.rollback(); } catch (SQLException ex) { ex.printStackTrace(); } } e.printStackTrace(); LogUtil.saveInfoLog(param.getString("ywxType") + "/" + userId, e); } finally { DBUtil.close(rs, ps, conn); } } /** 记录用户打开原邮件里的超链接的行为 */ public static void recordFromOriginalMailInfo2( final HttpServletRequest request, HttpServletResponse response) { Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; int ywxType = Integer.valueOf(request.getParameter("ywxType") .toString().replace("3D", "")); Integer userId2 = 0; Integer companyId2 = 0; if (ywxType == 9) {//9(sale100.com独立)营销邮邮件里需要跟踪的超链 ywxType = 3; Map<String, Object> userInfo = CentreDBUtil.getUserInfo(request.getParameter("ywxUid"), request.getParameter("ywxCid")); if (!userInfo.get("code").equals(200)) { System.err.println("获取用户信息失败:" + userInfo.get("msg")); return; } userId2 = Integer.valueOf(userInfo.get("userId").toString()); companyId2 = Integer.valueOf(userInfo.get("companyId").toString()); } else { userId2 = Integer .valueOf(request.getParameter("ywxUid") == null ? "0" : request .getParameter("ywxUid").replace("3D", "")); companyId2 = Integer.valueOf(request .getParameter("ywxCid") == null ? "0" : request .getParameter("ywxCid").replace("3D", "")); } final Integer userId = userId2; final Integer companyId = companyId2; try { String ip = NetworkUtil.getIpAddress(request); if (ip != null && !ip.equalsIgnoreCase("unknown") && !ip.equalsIgnoreCase("null")) { final String toMail = (request.getParameter("ywxMail") != null && request .getParameter("ywxMail").startsWith("3D")) ? URLDecoder.decode(request .getParameter("ywxMail").replaceFirst("3D", ""), "UTF-8") : URLDecoder.decode(request.getParameter("ywxMail"), "UTF-8");// 点读地址 final String mailUid = (request.getParameter("ywxMid") != null && request .getParameter("ywxMid").startsWith("3D")) ? URLDecoder.decode(request .getParameter("ywxMid").replaceFirst("3D", ""), "UTF-8") : URLDecoder.decode(request.getParameter("ywxMid"), "UTF-8");// 邮件唯一码 Boolean cookieEnabled = Boolean.valueOf(request.getParameter( "ywxCookie").replace("3D", "")); Integer ywxX = Integer .valueOf(request.getParameter("ywxX") == null ? "0" : request.getParameter("ywxX") .replace("3D", "")); Integer ywxH = Integer .valueOf(request.getParameter("ywxH") == null ? "0" : request.getParameter("ywxH") .replace("3D", "")); String poporimap = request.getParameter("poporimap");//null/0是pop,1是imap poporimap = poporimap == null ? "0" : poporimap.replace("3D", "").trim(); String jsessionId = request.getSession().getId(); if (toMail == null || mailUid == null || userId == null || companyId == null || cookieEnabled == null || ywxX == null || ywxH == null) { System.err.println("参数缺失"); return; } String uid = null; List<String> emails = new ArrayList<String>(); Cookie[] cookies = request.getCookies(); if (cookies != null && cookies.length > 0) { for (Cookie cookie : cookies) { if (ConstantUtil.USER_IDENTITY_COOKIE.equals(cookie .getName())) { uid = cookie.getValue(); } if (cookie.getName().startsWith( ConstantUtil.EMAIL_IDENTITY_COOKIE)) { if (cookie.getValue() != null && emailPattern.matcher(cookie.getValue()) .matches()) { emails.add(cookie.getValue()); } } } } Map<String, Object> mailInfo = null; String title = (request.getParameter("ywxTitle") != null && request .getParameter("ywxTitle").startsWith("3D")) ? request .getParameter("ywxTitle").replaceFirst("3D", "") : request.getParameter("ywxTitle"); if (title == null || title.trim().isEmpty() || title.equals("null")) { if (ywxType == 3) { mailInfo = YxyDBUtil.getMailInfo(mailUid); if (!mailInfo.get("code").equals(200)) { System.err.println("获取邮件信息失败:" + mailInfo.get("msg")); // return; } } else { mailInfo = WebmailDBUtil.getMailInfo(mailUid); if (!mailInfo.get("code").equals(200)) { System.err.println("获取邮件信息失败:" + mailInfo.get("msg")); // return; } } if (mailInfo.containsKey("subject")) { title = String.valueOf(mailInfo.get("subject")); } if (title != null && title.contains("###")) { title = title.split("###")[0]; } } conn = DBUtil.getConnection(); conn.setAutoCommit(false);// 开启事务 String sql = null; long count = 0L; String dbuid = null;// 邮箱在数据库中的第一条记录下的cookie标识 if (toMail != null && !toMail.trim().isEmpty()) { sql = "select identity from ts_customer_access where access_email = ? order by create_time ASC limit 1"; ps = conn.prepareStatement(sql); ps.setString(1, toMail); rs = ps.executeQuery(); if (rs.first()) { dbuid = rs.getString("identity"); } if (dbuid != null && !dbuid.equals(uid)) { uid = dbuid; } } // cookie里面没有UID则查该ip是否有浏览过,若有的话,则该用户的浏览器不支持cookie if (uid == null) { if (!cookieEnabled) {// 浏览器不支持cookie sql = "select identity,jsession_id from ts_customer_access where ip = ? order by create_time asc"; ps = conn.prepareStatement(sql); ps.setString(1, ip); rs = ps.executeQuery(); if (rs.first()) {// 有浏览过 cookieEnabled = false; uid = rs.getString("identity"); jsessionId = rs.getString("jsession_id"); sql = "select identity from ts_customer_email where email = ?"; ps = conn.prepareStatement(sql); ps.setString(1, toMail); rs = ps.executeQuery(); if (rs.first()) { // 若是数据库已经存在cookie唯一标示,而又不对应,则替换 // 在搜索引擎的爬虫下会造成数据混乱 // if (!uid.equals(rs.getString("identity"))) { // sql = // "update ts_customer_access set identity = ? , access_email = ? where identity = ?"; // ps = conn.prepareStatement(sql); // ps.setString(1, rs.getString("identity")); // ps.setString(2, toMail); // ps.setString(3, uid); // // ps.executeUpdate(); // // uid = rs.getString("identity"); // } } else { sql = "select count(*) from ts_customer_email where identity = ? and email = ?"; ps = conn.prepareStatement(sql); ps.setString(1, uid); ps.setString(2, toMail); rs = ps.executeQuery(); if (rs.first()) { count = rs.getLong(1); } if (count == 0L) { sql = "insert into ts_customer_email(identity,email,create_time) values(?,?,?)"; ps = conn.prepareStatement(sql); ps.setString(1, uid); ps.setString(2, toMail); ps.setString(3, DateFormat.getNowDate()); // 添加email ps.executeUpdate(); } } } } // 没有浏览过 if (uid == null) { sql = "select identity from ts_customer_email where email = ?"; ps = conn.prepareStatement(sql); ps.setString(1, toMail); rs = ps.executeQuery(); if (rs.first()) { uid = rs.getString("identity"); } else { uid = UUID.randomUUID().toString(); } sql = "insert into ts_customer(identity,type,create_time) values(?,?,?)"; ps = conn.prepareStatement(sql); ps.setString(1, uid); ps.setInt(2, 1);// 客户类型,0:路人、1:已存在客户 ps.setString(3, DateFormat.getNowDate()); // 添加客户 ps.executeUpdate(); sql = "select count(*) from ts_customer_email where identity = ? and email = ?"; ps = conn.prepareStatement(sql); ps.setString(1, uid); ps.setString(2, toMail); rs = ps.executeQuery(); if (rs.first()) { count = rs.getLong(1); } if (count == 0L) { sql = "insert into ts_customer_email(identity,email,create_time) values(?,?,?)"; ps = conn.prepareStatement(sql); ps.setString(1, uid); ps.setString(2, toMail); ps.setString(3, DateFormat.getNowDate()); // 添加email ps.executeUpdate(); } } } else { // sql = // "select identity from ts_customer_email where email = ?"; // ps = conn.prepareStatement(sql); // ps.setString(1, toMail); // String identity = null; // rs = ps.executeQuery(); // if (rs.first()) { // identity = rs.getString("identity"); // } // // 若是已经存在cookie唯一标示,而数据库又有该邮箱的cookie,则替换 // 在搜索引擎的爬虫下会造成数据混乱 // if (identity != null && !uid.equals(identity)) { // sql = // "update ts_customer_access set identity = ? , access_email = ? where identity = ?"; // ps = conn.prepareStatement(sql); // ps.setString(1, identity); // ps.setString(2, toMail); // ps.setString(3, uid); // // ps.executeUpdate(); // // uid = identity; // } // 浏览器没有该客户邮箱且数据没有保存,则保存 if (!emails.contains(toMail)) { sql = "select count(*) from ts_customer_email where identity = ? and email = ?"; ps = conn.prepareStatement(sql); ps.setString(1, uid); ps.setString(2, toMail); rs = ps.executeQuery(); if (rs.first()) { count = rs.getLong(1); } if (count == 0L) { sql = "insert into ts_customer_email(identity,email,create_time) values(?,?,?)"; ps = conn.prepareStatement(sql); ps.setString(1, uid); ps.setString(2, toMail); ps.setString(3, DateFormat.getNowDate()); // 添加email ps.executeUpdate(); } } } if (!emails.contains(toMail)) { emails.add(toMail); } // 数据组装 String agentString = request.getHeader("User-Agent"); String referer = request.getParameter("ywxReferrer"); String fromDomain = null; if (referer != null && !referer.trim().isEmpty()) { try { referer = URLDecoder.decode(referer, "UTF-8"); fromDomain = new URL(referer).getHost(); } catch (Exception e) { System.err.println("referer域名解析失败:" + e.getClass().getName() + (e.getMessage() == null ? "" : ("->" + e .getMessage()))); } } String language = request.getLocale().getLanguage(); if (request.getLocale().getCountry() != null && !request.getLocale().getCountry().trim().isEmpty()) { language += "-" + request.getLocale().getCountry(); } String accessUrl = (request.getParameter("ywxTo") != null && request .getParameter("ywxTo").startsWith("3D")) ? request .getParameter("ywxTo").replaceFirst("3D", "") : request .getParameter("ywxTo"); // final String accessUrl2 = accessUrl; String accessDomain = null; if (accessUrl != null) { try { accessUrl = URLDecoder.decode(accessUrl, "UTF-8"); accessDomain = new URL(accessUrl).getHost(); } catch (Exception e) { System.err.println("ywxTo域名解析失败:" + e.getClass().getName() + (e.getMessage() == null ? "" : ("->" + e .getMessage()))); } } // 解析ip String url = controlCentreUrl + "/webservice/ip"; Map<String, Object> params = new HashMap<String, Object>(); params.put("ip", ip); String continent = null; String country = null; String province = null; String city = null; String address = null; String netProvider = null; Map<String, Object> result = HttpUtil.doGet(url, params); if (result.get("code").equals(200)) { Object data = result.get("data"); JSONObject json = JSONObject.fromObject(data); if (json.getInt("code") == 200) { json = JSONObject.fromObject(json.get("result")); netProvider = json.getString("isp"); continent = json.getString("land"); country = json.getString("country"); province = json.getString("prov"); city = json.getString("city"); address = json.getString("dist"); } else { System.err.println("ip解析失败:" + json.get("result")); } } else { System.err.println("ip解析失败:" + result.get("msg")); } UserAgent userAgent = UserAgent .parseUserAgentString(agentString); if ((accessUrl == null || accessUrl.trim().isEmpty()) || (mailUid == null || mailUid.trim().isEmpty()) || (toMail == null || toMail.trim().isEmpty())) { // 只要有一个为空就放弃添加 return; } if (toMail != null && !toMail.trim().isEmpty()) { if (!emailPattern.matcher(toMail.trim().toLowerCase()) .matches()) { // 邮箱格式错误就放弃添加 return; } } // 添加浏览记录 sql = "insert into ts_customer_access(identity,user_id,company_id,mail_uid,title,from_url,from_domain,access_url,access_domain,ip,jsession_id,continent,country,province,city,address,device_type,browser_name,language,screen_x,screen_y,net_provider,os,search_word,user_agent,cookie_enable,access_time,access_email,res_type,create_time,template_id,customer_id,from_type,count_id,status,is_imap) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; ps = conn.prepareStatement(sql); ps.setString(1, uid);// cookie唯一标示 ps.setInt(2, userId);// 用户id ps.setInt(3, companyId);// 企业id ps.setString(4, mailUid);// 邮件唯一标示 ps.setString(5, title);// 来源标题 ps.setString(6, referer);// 来源url ps.setString(7, fromDomain);// 来源域名 ps.setString(8, accessUrl);// 受访问url ps.setString(9, accessDomain);// 受访问域名 ps.setString(10, ip);// 客户端ip ps.setString(11, jsessionId);// 回话id ps.setString(12, continent);// 访问者所属洲 ps.setString(13, country);// 访问者所属国际 ps.setString(14, province);// //访问者所属省份 ps.setString(15, city);// //访问者所属城市 ps.setString(16, address);// //访问者所属详细地址 ps.setInt(17, TrackUtil.getDeviceType(userAgent));// 设备类型 ps.setString(18, userAgent.getBrowser().getName());// 浏览器名称 ps.setString(19, language);// 浏览器设置的语言 ps.setInt(20, ywxX);// 设备宽度 ps.setInt(21, ywxH);// 设备高度 ps.setString(22, netProvider);// 网络接入商 ps.setString(23, userAgent.getOperatingSystem().getName());// 操作系统名称 ps.setString(24, TrackUtil.getSearchWord(referer));// 搜索词 ps.setString(25, agentString);// 浏览器ua ps.setInt(26, cookieEnabled ? 1 : 0);// 是否支持cookie,1支持、0不支持 ps.setInt(27, 0);// 访问时长,单位毫秒 ps.setString(28, toMail);// 客户邮箱 ps.setInt(29, ywxType);// 受访问资源类型,0营销邮邮件、1营销邮邮件HTML页面、2易外销用户站点、3营销邮邮件里需要跟踪的超链、4营销邮邮件HTML页面里需要跟踪的超链、5易外销邮件、6易外销邮件里需要跟踪的超链、7询盘 ps.setString(30, DateFormat.getNowDate());// 创建时间 ps.setInt(31, 0);// 模板id ps.setInt(32, WebmailDBUtil.getCustomerId(userId, toMail));// 客户id ps.setInt(33, 3);// 来源类别,-1无来源url、0:外链、1社交、2搜索、3邮件 ps.setLong(34, 0L);// 统计id ps.setInt(35, 1);// 状态,0删除、1正常 ps.setInt(36, Integer.valueOf(poporimap));// 是否是imap邮件,0否、1是 // 提交添加 ps.executeUpdate(); // 获取自动生成的id rs = ps.getGeneratedKeys(); long id = 0L; if (rs.first()) { id = rs.getLong(1); } // final long aid = id; sql = "select id,create_time from ts_customer_access where id != ? and identity = ? and user_id = ? and company_id = ? and to_days(create_time) = to_days(now()) order by create_time desc"; ps = conn.prepareStatement(sql); ps.setLong(1, id); ps.setString(2, uid); ps.setInt(3, userId); ps.setInt(4, companyId); // 有上一条记录则修改上一条记录的访问时长 rs = ps.executeQuery(); if (rs.first()) { long milliSeconds = DateFormat.milliSeconds( rs.getString("create_time"), DateFormat.getNowDate()); if (milliSeconds < (1000 * 60 * 60 * 2)) {// 当天前后两个请求大于2个小时的丢掉 sql = "update ts_customer_access set access_time = ? where id = ?"; ps = conn.prepareStatement(sql); ps.setLong(1, milliSeconds); ps.setLong(2, rs.getLong("id")); // 修改上一个请求的访问时长 ps.executeUpdate(); } } // 修改为已存在客户 // sql = "update ts_customer set type = ? where identity = ?"; // ps = conn.prepareStatement(sql); // ps.setInt(1, 1);// 客户类型,0:路人、1:已存在客户 // ps.setString(2, uid); // // 修改客户 // ps.executeUpdate(); // 设置cookie String serverDomain = request.getServerName(); int len = 0; if (!ipPattern.matcher(serverDomain).matches()) { String[] domains = serverDomain.split("\\."); len = domains.length; if (len > 2) { serverDomain = domains[len - 2] + "." + domains[len - 1]; } } Cookie cookie = new Cookie(ConstantUtil.USER_IDENTITY_COOKIE, uid); cookie.setMaxAge(ConstantUtil.HALF_CENTURY); cookie.setDomain(serverDomain); response.addCookie(cookie); len = emails.size(); for (int i = 0; i < len; i++) { cookie = new Cookie(ConstantUtil.EMAIL_IDENTITY_COOKIE + "_" + i, emails.get(i)); cookie.setMaxAge(ConstantUtil.HALF_CENTURY); cookie.setDomain(serverDomain); response.addCookie(cookie); } final int recordType = ywxType; final long recordId = id; final String recordEmail = toMail; final String recordLink = (accessUrl == null ? null : URLDecoder.decode(accessUrl, "UTF-8")); final int recordUserId = userId; // 点击超链接时异步添加消息提醒:3营销邮邮件里需要跟踪的超链、6易外销邮件里需要跟踪的超链 if (recordLink != null && !recordLink.trim().isEmpty() && recordEmail != null && !recordEmail.trim().isEmpty() && Arrays.asList(3, 6).contains(recordType)) { fixedThreadPool.execute(new Runnable() { public void run() { System.out.println("开始添加邮件里超链点击消息提醒和统计..."); if (mailUid != null && !mailUid.trim().isEmpty() && recordType == 6) { System.out.println("开始添加邮件里超链点击统计..."); Connection conn3 = null; PreparedStatement ps3 = null; ResultSet rs3 = null; try { int tryCount = 0; conn3 = DBUtil.getConnection(); String sql2 = "select count(*) from ts_customer_access where res_type = 6 and access_url = ? and access_email = ? and user_id = ? and company_id = ? and mail_uid = ?"; ps3 = conn3.prepareStatement(sql2); ps3.setObject(1, recordLink); ps3.setObject(2, recordEmail); ps3.setObject(3, userId); ps3.setObject(4, companyId); ps3.setObject(5, mailUid); int cou = 0; rs3 = ps3.executeQuery(); if (rs3.first()) { cou = rs3.getInt(1); } if (cou <= 1) {//超过1条记录则不统计 Connection conn2 = null; PreparedStatement ps2 = null; ResultSet rs2 = null; while (conn2 == null && tryCount < 3) { tryCount++; try { conn2 = WebmailDBUtil.getConnection(); } catch (Exception e) { e.printStackTrace(); try { Thread.sleep(5000); } catch (InterruptedException ex) { ex.printStackTrace(); } } } sql2 = "select id from attr_link_count where mail_uid = ?"; ps2 = conn2.prepareStatement(sql2); ps2.setObject(1, mailUid); rs2 = ps2.executeQuery(); if (rs2.first()) {//已存在 cou = rs2.getInt(1); rs2.close(); ps2.close(); sql2 = "update attr_link_count set link_count = link_count + 1 where id = ?"; ps2 = conn2.prepareStatement(sql2); ps2.setObject(1, cou); ps2.executeUpdate(); } else {//未存在 rs2.close(); ps2.close(); sql2 = "insert into attr_link_count(mail_uid,file_count,link_count) values(?,?,?)"; ps2 = conn2.prepareStatement(sql2); ps2.setObject(1, mailUid); ps2.setObject(2, 0); ps2.setObject(3, 1); ps2.executeUpdate(); } //conn2.commit(); WebmailDBUtil.close(rs2, ps2, conn2); } } catch (SQLException ex) { ex.printStackTrace(); } finally { DBUtil.close(rs3, ps3, conn3); } } String title = null; Map<String, Object> mailInfo = null; if (recordType == 3) { mailInfo = YxyDBUtil.getMailInfo(mailUid); if (!mailInfo.get("code").equals(200)) { System.err.println("获取邮件信息失败:" + mailInfo.get("msg")); // return; } } else { mailInfo = WebmailDBUtil.getMailInfo(mailUid); if (!mailInfo.get("code").equals(200)) { System.err.println("获取邮件信息失败:" + mailInfo.get("msg")); // return; } } if (mailInfo.containsKey("subject")) { title = String.valueOf(mailInfo.get("subject")); } if (title != null && title.contains("###")) { title = title.split("###")[0]; } if (title == null || title.trim().isEmpty()) { title = "未知"; } Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; try { //一个封邮件里的一个超链接一天提醒一次 // 《xx》邮箱点开了您邮件/模板《xx》里的超链接《xx》 conn = WebmailDBUtil.getConnection(); String sql = "select id from sys_user_remind where to_days(remind_time) = to_days(now()) and remind_content like '《" + recordEmail.trim() + "》%点开了您邮件《" + title.trim() + "》%超链接《" + recordLink.trim() + "》%' and remind_userid = " + recordUserId; ps = conn.prepareStatement(sql); rs = ps.executeQuery(); int id = 0; if (rs.first()) { id = rs.getInt("id"); System.out.println("已有消息id:" + id); } if (id == 0) { String content = "《"+recordEmail.trim()+"》邮箱点开了您邮件《"+title.trim()+"》里的超链接《"+recordLink.trim()+"》,请前往追踪统计查看!"; sql = "insert into sys_user_remind(remind_userid,remind_type,remind_status,remind_time,remind_content,target_id,is_read) values(?,?,?,?,?,?,?)"; ps = conn.prepareStatement(sql); ps.setObject(1, recordUserId); ps.setObject(2, 21); ps.setObject(3, 0); ps.setObject(4, DateFormat.getNowDate()); ps.setObject(5, content); ps.setObject(6, recordId); ps.setObject(7, 0); ps.executeUpdate(); System.out.println("消息提醒添加完成"); } } catch (Exception e) { e.printStackTrace(); } finally { WebmailDBUtil.close(rs, ps, conn); } } }); } // 异步统计邮件里的超链 // singleThreadExecutor.execute(new Runnable() { // // public void run() { // // TrackUtil.countLink(userId, companyId, mailUid, // accessUrl2, toMail, aid); // } // }); // try的最后提交事务 conn.commit(); } else { System.err.println("无法获取ip"); } } catch (Exception e) { if (conn != null) { try { // 回滚事务 conn.rollback(); } catch (SQLException ex) { ex.printStackTrace(); } } e.printStackTrace(); LogUtil.saveInfoLog(request.getParameter("ywxType") + "/" + userId, e); } finally { DBUtil.close(rs, ps, conn); } } /** 记录用户打开SEO HTML邮件里的超链接、及其本身HTML页面和用户官网的行为 */ public static void recordFromHtmlInfo(HttpServletRequest request, HttpServletResponse response) { Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; Integer userId = 0; try { String ip = NetworkUtil.getIpAddress(request); if (ip != null && !ip.equalsIgnoreCase("unknown") && !ip.equalsIgnoreCase("null")) { Integer templateId = Integer.valueOf(request .getParameter("ywxMid") == null ? "0" : request .getParameter("ywxMid"));// 邮件模板id userId = Integer .valueOf(request.getParameter("ywxUid") == null ? "0" : request.getParameter("ywxUid")); Integer companyId = Integer.valueOf(request .getParameter("ywxCid") == null ? "0" : request .getParameter("ywxCid")); Boolean cookieEnabled = Boolean.valueOf(request .getParameter("ywxCookie")); Integer ywxX = Integer .valueOf(request.getParameter("ywxX") == null ? "0" : request.getParameter("ywxX")); Integer ywxH = Integer .valueOf(request.getParameter("ywxH") == null ? "0" : request.getParameter("ywxH")); String poporimap = request.getParameter("poporimap");//null/0是pop,1是imap poporimap = poporimap == null ? "0" : poporimap.replace("3D", "").trim(); String jsessionId = request.getSession().getId(); if (userId == null || companyId == null || cookieEnabled == null || ywxX == null || ywxH == null) { System.err.println("参数缺失"); return; } String uid = null; List<String> emails = new ArrayList<String>(); Cookie[] cookies = request.getCookies(); if (cookies != null && cookies.length > 0) { for (Cookie cookie : cookies) { if (ConstantUtil.USER_IDENTITY_COOKIE.equals(cookie .getName())) { uid = cookie.getValue(); } if (cookie.getName().startsWith( ConstantUtil.EMAIL_IDENTITY_COOKIE)) { if (cookie.getValue() != null && emailPattern.matcher(cookie.getValue()) .matches()) { emails.add(cookie.getValue()); } } } } Integer ywxType = Integer.valueOf(request .getParameter("ywxType") == null ? request .getAttribute("ywxType").toString() : request .getParameter("ywxType")); String title = request.getParameter("ywxTitle"); if (ywxType == 1 || ywxType == 4) { if (title == null || title.trim().isEmpty() || title.equals("null")) { Map<String, Object> templateInfo = YxyDBUtil .getTemplateInfo(templateId); if (!templateInfo.get("code").equals(200)) { System.err.println("获取模板信息失败:" + templateInfo.get("msg")); // return; } else { title = String.valueOf(templateInfo.get("subject")); } } } conn = DBUtil.getConnection(); conn.setAutoCommit(false);// 开启事务 String sql = null; long count = 0L; String toMail = request.getParameter("ywxMail"); if (toMail != null) { toMail = URLDecoder.decode(toMail, "UTF-8"); } Map<String, Object> linkInfo = null; // cookie里面没有UID则查该ip是否有浏览过,若有的话,则该用户的浏览器不支持cookie if (uid == null) { if (!cookieEnabled) {// 浏览器不支持cookie sql = "select identity,jsession_id from ts_customer_access where ip = ? order by create_time asc"; ps = conn.prepareStatement(sql); ps.setString(1, ip); rs = ps.executeQuery(); if (rs.first()) {// 有浏览过 uid = rs.getString("identity"); jsessionId = rs.getString("jsession_id"); sql = "select email from ts_customer_email where identity = ?"; ps = conn.prepareStatement(sql); ps.setString(1, uid); String ems = ""; rs = ps.executeQuery(); while (rs.next()) { ems += ",'" + rs.getString("email") + "'"; } if (request.getParameter("ywxMail") != null) { ems += ",'" + request.getParameter("ywxMail") + "'"; } if (ems.trim().length() > 0) { ems = ems.substring(1); linkInfo = WebmailDBUtil.getUserEmail(userId, companyId, ems); toMail = String.valueOf(linkInfo.get("email")); if (ywxType != 8 && linkInfo.get("userId") != null) { userId = Integer.valueOf(linkInfo.get( "userId").toString()); } } } } // 没有浏览过 if (uid == null) { uid = UUID.randomUUID().toString(); sql = "insert into ts_customer(identity,type,create_time) values(?,?,?)"; ps = conn.prepareStatement(sql); ps.setString(1, uid); ps.setInt(2, 1);// 客户类型,0:路人、1:已存在客户 ps.setString(3, DateFormat.getNowDate()); // 添加客户 ps.executeUpdate(); if (toMail != null && !toMail.equals("null")) { sql = "select count(*) from ts_customer_email where identity = ? and email = ?"; ps = conn.prepareStatement(sql); ps.setString(1, uid); ps.setString(2, toMail); rs = ps.executeQuery(); if (rs.first()) { count = rs.getLong(1); } if (count == 0L) { sql = "insert into ts_customer_email(identity,email,create_time) values(?,?,?)"; ps = conn.prepareStatement(sql); ps.setString(1, uid); ps.setString(2, toMail); ps.setString(3, DateFormat.getNowDate()); // 添加email ps.executeUpdate(); } } } } else { String ems = ""; if (emails.size() > 0) {// 浏览器里有邮箱 for (String email : emails) { ems += ",'" + email + "'"; } if (request.getParameter("ywxMail") != null) { ems += ",'" + request.getParameter("ywxMail") + "'"; } if (ems.trim().length() > 0) { ems = ems.substring(1); linkInfo = WebmailDBUtil.getUserEmail(userId, companyId, ems); toMail = String.valueOf(linkInfo.get("email")); if (ywxType != 8 && linkInfo.get("userId") != null) { userId = Integer.valueOf(linkInfo.get("userId") .toString()); } } // 浏览器有客户邮箱且数据没有保存,则保存 if (toMail != null && !toMail.equals("null")) { sql = "select count(*) from ts_customer_email where identity = ? and email = ?"; ps = conn.prepareStatement(sql); ps.setString(1, uid); ps.setString(2, toMail); rs = ps.executeQuery(); if (rs.first()) { count = rs.getLong(1); } if (count == 0L) { sql = "insert into ts_customer_email(identity,email,create_time) values(?,?,?)"; ps = conn.prepareStatement(sql); ps.setString(1, uid); ps.setString(2, toMail); ps.setString(3, DateFormat.getNowDate()); // 添加email ps.executeUpdate(); } } } else {// 浏览器里没有邮箱 sql = "select email from ts_customer_email where identity = ?"; ps = conn.prepareStatement(sql); ps.setString(1, uid); rs = ps.executeQuery(); while (rs.next()) { ems += ",'" + rs.getString("email") + "'"; } if (request.getParameter("ywxMail") != null) { ems += ",'" + request.getParameter("ywxMail") + "'"; } if (ems.trim().length() > 0) { ems = ems.substring(1); linkInfo = WebmailDBUtil.getUserEmail(userId, companyId, ems); toMail = String.valueOf(linkInfo.get("email")); if (ywxType != 8 && linkInfo.get("userId") != null) { userId = Integer.valueOf(linkInfo.get("userId") .toString()); } } } } if ((toMail == null || toMail.trim().isEmpty() || toMail .equals("null")) && request.getParameter("ywxMail") != null) { toMail = request.getParameter("ywxMail"); } if (toMail != null && !toMail.equals("null") && !emails.contains(toMail)) { emails.add(toMail); } // 数据组装 String agentString = request.getHeader("User-Agent"); String referer = request.getParameter("ywxReferrer"); String fromDomain = null; if (referer != null && !referer.trim().isEmpty()) { try { referer = URLDecoder.decode(referer, "UTF-8"); fromDomain = new URL(referer).getHost(); } catch (Exception e) { System.err.println("referer域名解析失败:" + e.getClass().getName() + (e.getMessage() == null ? "" : ("->" + e .getMessage()))); } } String language = request.getLocale().getLanguage(); if (request.getLocale().getCountry() != null && !request.getLocale().getCountry().trim().isEmpty()) { language += "-" + request.getLocale().getCountry(); } String accessUrl = request.getParameter("ywxTo"); String accessDomain = null; if (accessUrl != null) { try { accessUrl = URLDecoder.decode(accessUrl, "UTF-8"); accessDomain = new URL(accessUrl).getHost(); } catch (Exception e) { System.err.println("ywxTo域名解析失败:" + e.getClass().getName() + (e.getMessage() == null ? "" : ("->" + e .getMessage()))); } } // 解析ip String url = controlCentreUrl + "/webservice/ip"; Map<String, Object> params = new HashMap<String, Object>(); params.put("ip", ip); String continent = null; String country = null; String province = null; String city = null; String address = null; String netProvider = null; JSONObject areaJson = null; Map<String, Object> result = HttpUtil.doGet(url, params); if (result.get("code").equals(200)) { Object data = result.get("data"); areaJson = JSONObject.fromObject(data); if (areaJson.getInt("code") == 200) { areaJson = JSONObject.fromObject(areaJson.get("result")); netProvider = areaJson.getString("isp"); continent = areaJson.getString("land"); country = areaJson.getString("country"); province = areaJson.getString("prov"); city = areaJson.getString("city"); address = areaJson.getString("dist"); } else { System.err.println("ip解析失败:" + areaJson.get("result")); } } else { System.err.println("ip解析失败:" + result.get("msg")); } UserAgent userAgent = UserAgent .parseUserAgentString(agentString); if (toMail != null && toMail.equals("null")) { toMail = null; } if (toMail == null && emails.size() > 0) { toMail = emails.get(0); } if (userId == null || userId == 0) { // 没有用户id则获取设置id userId = WebmailDBUtil.getUserId(companyId, accessUrl); // 没有用户id则获取管理员id if (userId == 0) { userId = CentreDBUtil.getUserId(companyId); } } if (toMail != null && !toMail.trim().isEmpty()) { if (!emailPattern.matcher(toMail.trim().toLowerCase()) .matches()) { // 邮箱格式错误就放弃添加 System.err.println("邮箱格式错误就放弃添加:" + toMail); return; } } toMail = ywxType == 7 ? request.getParameter("ywxMail") : toMail; String dbuid = null;// 邮箱在数据库中的第一条记录下的cookie标识 if (toMail != null && !toMail.trim().isEmpty()) { sql = "select identity from ts_customer_access where access_email = ? order by create_time ASC limit 1"; ps = conn.prepareStatement(sql); ps.setString(1, toMail); rs = ps.executeQuery(); if (rs.first()) { dbuid = rs.getString("identity"); } if (dbuid != null && !dbuid.equals(uid)) { uid = dbuid; } } if (toMail != null && !toMail.trim().isEmpty() && !toMail.equalsIgnoreCase("null")) { sql = "select count(*) from ts_customer_email where identity = ? and email = ?"; ps = conn.prepareStatement(sql); ps.setString(1, uid); ps.setString(2, toMail); rs = ps.executeQuery(); if (rs.first()) { count = rs.getLong(1); } if (count == 0L) { sql = "insert into ts_customer_email(identity,email,create_time) values(?,?,?)"; ps = conn.prepareStatement(sql); ps.setString(1, uid); ps.setString(2, toMail); ps.setString(3, DateFormat.getNowDate()); // 添加email ps.executeUpdate(); } } final int customerId = WebmailDBUtil.getCustomerId(userId, toMail); // 添加浏览记录 sql = "insert into ts_customer_access(identity,user_id,company_id,mail_uid,title,from_url,from_domain,access_url,access_domain,ip,jsession_id,continent,country,province,city,address,device_type,browser_name,language,screen_x,screen_y,net_provider,os,search_word,user_agent,cookie_enable,access_time,access_email,res_type,create_time,template_id,customer_id,from_type,count_id,status,is_imap) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; ps = conn.prepareStatement(sql); ps.setString(1, uid);// cookie唯一标示 ps.setInt(2, userId);// 用户id ps.setInt(3, companyId);// 企业id ps.setString(4, null);// 邮件唯一标示 ps.setString(5, title);// 来源标题 ps.setString(6, referer);// 来源url ps.setString(7, fromDomain);// 来源域名 ps.setString(8, accessUrl);// 受访问url ps.setString(9, accessDomain);// 受访问域名 ps.setString(10, ip);// 客户端ip ps.setString(11, jsessionId);// 回话id ps.setString(12, continent);// 访问者所属洲 ps.setString(13, country);// 访问者所属国际 ps.setString(14, province);// //访问者所属省份 ps.setString(15, city);// //访问者所属城市 ps.setString(16, address);// //访问者所属详细地址 ps.setInt(17, TrackUtil.getDeviceType(userAgent));// 设备类型 ps.setString(18, userAgent.getBrowser().getName());// 浏览器名称 ps.setString(19, language);// 浏览器设置的语言 ps.setInt(20, ywxX);// 设备宽度 ps.setInt(21, ywxH);// 设备高度 ps.setString(22, netProvider);// 网络接入商 ps.setString(23, userAgent.getOperatingSystem().getName());// 操作系统名称 ps.setString(24, TrackUtil.getSearchWord(referer));// 搜索词 ps.setString(25, agentString);// 浏览器ua ps.setInt(26, cookieEnabled ? 1 : 0);// 是否支持cookie,1支持、0不支持 ps.setInt(27, 0);// 访问时长,单位毫秒 ps.setString(28, toMail);// 客户邮箱 ps.setInt(29, ywxType);// 受访问资源类型,0营销邮邮件、1营销邮邮件HTML页面、2易外销用户站点、3营销邮邮件里需要跟踪的超链、4营销邮邮件HTML页面里需要跟踪的超链、5易外销邮件、6易外销邮件里需要跟踪的超链、7询盘 ps.setString(30, DateFormat.getNowDate());// 创建时间 ps.setInt(31, templateId);// 模板id ps.setInt(32, customerId);// 客户id ps.setInt(33, TrackUtil.getFromType(referer));// 来源类别,-1无来源url、0:外链、1社交、2搜索、3邮件 ps.setLong(34, 0L);// 统计id ps.setInt(35, 1);// 状态,0删除、1正常 ps.setInt(36, Integer.valueOf(poporimap));// 是否是imap邮件,0否、1是 // 提交添加 ps.executeUpdate(); // 获取自动生成的id rs = ps.getGeneratedKeys(); long id = 0L; if (rs.first()) { id = rs.getLong(1); } sql = "select id,create_time from ts_customer_access where id != ? and identity = ? and user_id = ? and company_id = ? and to_days(create_time) = to_days(now()) order by create_time desc"; ps = conn.prepareStatement(sql); ps.setLong(1, id); ps.setString(2, uid); ps.setInt(3, userId); ps.setInt(4, companyId); // 有上一条记录则修改上一条记录的访问时长 rs = ps.executeQuery(); if (rs.first()) { long milliSeconds = DateFormat.milliSeconds( rs.getString("create_time"), DateFormat.getNowDate()); if (milliSeconds < (1000 * 60 * 60 * 2)) {// 当天前后两个请求大于2个小时的丢掉 sql = "update ts_customer_access set access_time = ? where id = ?"; ps = conn.prepareStatement(sql); ps.setLong(1, milliSeconds); ps.setLong(2, rs.getLong("id")); // 修改上一个请求的访问时长 ps.executeUpdate(); } } // 修改为已存在客户 // sql = "update ts_customer set type = ? where identity = ?"; // ps = conn.prepareStatement(sql); // ps.setInt(1, 1);// 客户类型,0:路人、1:已存在客户 // ps.setString(2, uid); // // 修改客户 // ps.executeUpdate(); // 设置cookie String serverDomain = request.getServerName(); int len = 0; if (!ipPattern.matcher(serverDomain).matches()) { String[] domains = serverDomain.split("\\."); len = domains.length; if (len > 2) { serverDomain = domains[len - 2] + "." + domains[len - 1]; } } Cookie cookie = new Cookie(ConstantUtil.USER_IDENTITY_COOKIE, uid); cookie.setMaxAge(ConstantUtil.HALF_CENTURY); cookie.setDomain(serverDomain); response.addCookie(cookie); emails.remove("null"); len = emails.size(); for (int i = 0; i < len; i++) { cookie = new Cookie(ConstantUtil.EMAIL_IDENTITY_COOKIE + "_" + i, emails.get(i)); cookie.setMaxAge(ConstantUtil.HALF_CENTURY); cookie.setDomain(serverDomain); response.addCookie(cookie); } final JSONObject areaJson2 = areaJson; final int recordType = ywxType; final long recordId = id; final String recordEmail = toMail; final String recordLink = (accessUrl == null ? null : URLDecoder.decode(accessUrl, "UTF-8")); final int recordUserId = userId; final int recordTemplateId = templateId; System.out.println("ok..."); // 点击超链接时异步添加消息提醒:4营销邮邮件HTML页面里需要跟踪的超链 if ((recordLink != null && !recordLink.trim().isEmpty()) && (recordType == 2 || recordType == 4)) { fixedThreadPool.execute(new Runnable() { public void run() { System.out.println("开始添加消息提醒,recordType:" + recordType); if (recordType == 2) { String chatType = "Unknown"; if (recordLink.startsWith("skype:live:")) { chatType = "Skype"; } else if (recordLink.startsWith("https://api.whatsapp.com/send")) { chatType = "WhatAPP"; } else if (recordLink.startsWith("http://wpa.qq.com/msgrd")) { chatType = "QQ"; } else if (recordLink.startsWith("http://amos.alicdn.com/msg.aw")) { chatType = "阿里旺旺"; } if (!chatType.equals("Unknown")) { System.out.println("开始添加页面在线咨询超链点击消息提醒..."); String name = null; if (customerId > 0) { name = WebmailDBUtil.getCustomerName(customerId); } if (name == null || name.trim().isEmpty()) { name = "新访客"; } String area = ""; if (areaJson2 != null && areaJson2.containsKey("country")) { String country2 = areaJson2.getString("country"); if (country2 != null && !country2.trim().isEmpty()) { area += country2; } String province2 = areaJson2.getString("prov"); if (province2 != null && !province2.trim().isEmpty()) { area += province2; } String city2 = areaJson2.getString("city"); if (city2 != null && !city2.trim().isEmpty()) { area += city2; } } if (area.isEmpty()) { area = "未知地区"; } Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; try { conn = WebmailDBUtil.getConnection(); //张三@@espeed@@美国@@espeed@@Skype String content = name + "@@espeed@@" + area + "@@espeed@@" + chatType; String sql = "insert into sys_user_remind(remind_userid,remind_type,remind_status,remind_time,remind_content,target_id,is_read) values(?,?,?,?,?,?,?)"; ps = conn.prepareStatement(sql); ps.setObject(1, recordUserId); ps.setObject(2, 32); ps.setObject(3, 0); ps.setObject(4, DateFormat.getNowDate()); ps.setObject(5, content); ps.setObject(6, recordId); ps.setObject(7, 0); ps.executeUpdate(); System.out.println("消息提醒添加完成"); } catch (Exception e) { e.printStackTrace(); } finally { WebmailDBUtil.close(rs, ps, conn); } } } else if (recordType == 4 && recordEmail != null && !recordEmail.trim().isEmpty()) { System.out.println("开始添加营销邮页面超链点击消息提醒..."); String title = null; Map<String, Object> templateInfo = YxyDBUtil .getTemplateInfo(recordTemplateId); if (!templateInfo.get("code").equals(200)) { System.err.println("获取模板信息失败:" + templateInfo.get("msg")); //return; } else { title = String.valueOf(templateInfo.get("subject")); } if (title == null || title.trim().isEmpty()) { title = "未知"; } Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; try { //一个封邮件里的一个超链接一天提醒一次 // 《xx》邮箱点开了您邮件/模板《xx》里的超链接《xx》 conn = WebmailDBUtil.getConnection(); String sql = "select id from sys_user_remind where to_days(remind_time) = to_days(now()) and remind_content like '《" + recordEmail.trim() + "》%点开了您模板《" + title.trim() + "》%超链接《" + recordLink.trim() + "》%' and remind_userid = " + recordUserId; ps = conn.prepareStatement(sql); rs = ps.executeQuery(); int id = 0; if (rs.first()) { id = rs.getInt("id"); } if (id == 0) { String content = "《"+recordEmail.trim()+"》邮箱点开了您模板《"+title.trim()+"》里的超链接《"+recordLink.trim()+"》,请前往追踪统计查看!"; sql = "insert into sys_user_remind(remind_userid,remind_type,remind_status,remind_time,remind_content,target_id,is_read) values(?,?,?,?,?,?,?)"; ps = conn.prepareStatement(sql); ps.setObject(1, recordUserId); ps.setObject(2, 21); ps.setObject(3, 0); ps.setObject(4, DateFormat.getNowDate()); ps.setObject(5, content); ps.setObject(6, recordId); ps.setObject(7, 0); ps.executeUpdate(); System.out.println("消息提醒添加完成"); } } catch (Exception e) { e.printStackTrace(); } finally { WebmailDBUtil.close(rs, ps, conn); } } } }); } // try的最后提交事务 conn.commit(); } else { System.err.println("无法获取ip"); } } catch (Exception e) { if (conn != null) { try { // 回滚事务 conn.rollback(); } catch (SQLException ex) { ex.printStackTrace(); } } e.printStackTrace(); LogUtil.saveInfoLog(request.getParameter("ywxType") + "/" + userId, e); } finally { DBUtil.close(rs, ps, conn); } } /** 记录用户打开SEO HTML邮件里的超链接、及其本身HTML页面和用户官网的行为 */ public static void recordFromHtmlInfo2(JSONObject param, List<String> emails) { Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; Integer userId = 0; try { String ip = param.getString("ip"); if (ip != null && !ip.equalsIgnoreCase("unknown") && !ip.equalsIgnoreCase("null")) { if (!param.containsKey("ywxMid")) { param.put("ywxMid", ""); } if (!param.containsKey("ywxUid")) { param.put("ywxUid", "0"); } if (!param.containsKey("ywxCid")) { param.put("ywxCid", "0"); } if (!param.containsKey("poporimap")) { param.put("poporimap", "0"); } if (!param.containsKey("ywxTitle")) { param.put("ywxTitle", ""); } if (!param.containsKey("ywxTo")) { param.put("ywxTo", ""); } if (!param.containsKey("ywxX")) { param.put("ywxX", ""); } if (!param.containsKey("ywxH")) { param.put("ywxH", ""); } if (!param.containsKey("ywxMail")) { param.put("ywxMail", ""); } if (!param.containsKey("ywxTitle")) { param.put("ywxTitle", ""); } Integer templateId = Integer.valueOf(param.getString("ywxMid") == null ? "0" : param.getString("ywxMid"));// 邮件模板id userId = Integer .valueOf(param.getString("ywxUid") == null ? "0" : param.getString("ywxUid")); Integer companyId = Integer.valueOf(param.getString("ywxCid") == null ? "0" : param.getString("ywxCid")); Boolean cookieEnabled = Boolean.valueOf(param.getString("ywxCookie")); Integer ywxX = Integer .valueOf(param.getString("ywxX") == null ? "0" : param.getString("ywxX")); Integer ywxH = Integer .valueOf(param.getString("ywxH") == null ? "0" : param.getString("ywxH")); String poporimap = param.getString("poporimap");//null/0是pop,1是imap poporimap = poporimap == null ? "0" : poporimap.replace("3D", "").trim(); String jsessionId = param.getString("jsessionId"); if (userId == null || companyId == null || cookieEnabled == null || ywxX == null || ywxH == null) { System.err.println("参数缺失"); return; } String uid = null; if (param.containsKey("uid")) { uid = param.getString("uid"); } Integer ywxType = Integer.valueOf(param.getString("ywxType")); String title = param.getString("ywxTitle"); if (ywxType == 1 || ywxType == 4) { if (title == null || title.trim().isEmpty() || title.equals("null")) { Map<String, Object> templateInfo = YxyDBUtil .getTemplateInfo(templateId); if (!templateInfo.get("code").equals(200)) { System.err.println("获取模板信息失败:" + templateInfo.get("msg")); // return; } else { title = String.valueOf(templateInfo.get("subject")); } } } conn = DBUtil.getConnection(); conn.setAutoCommit(false);// 开启事务 String sql = null; long count = 0L; String toMail = param.getString("ywxMail"); if (toMail != null) { toMail = URLDecoder.decode(toMail, "UTF-8"); } Map<String, Object> linkInfo = null; // cookie里面没有UID则查该ip是否有浏览过,若有的话,则该用户的浏览器不支持cookie if (uid == null) { if (!cookieEnabled) {// 浏览器不支持cookie sql = "select identity,jsession_id from ts_customer_access where ip = ? order by create_time asc"; ps = conn.prepareStatement(sql); ps.setString(1, ip); rs = ps.executeQuery(); if (rs.first()) {// 有浏览过 uid = rs.getString("identity"); jsessionId = rs.getString("jsession_id"); sql = "select email from ts_customer_email where identity = ?"; ps = conn.prepareStatement(sql); ps.setString(1, uid); String ems = ""; rs = ps.executeQuery(); while (rs.next()) { ems += ",'" + rs.getString("email") + "'"; } if (StringUtils.isNotEmpty(param.getString("ywxMail"))) { ems += ",'" + param.getString("ywxMail") + "'"; } if (ems.trim().length() > 0) { ems = ems.substring(1); linkInfo = WebmailDBUtil.getUserEmail(userId, companyId, ems); toMail = String.valueOf(linkInfo.get("email")); if (ywxType != 8 && linkInfo.get("userId") != null) { userId = Integer.valueOf(linkInfo.get( "userId").toString()); } } } } // 没有浏览过 if (uid == null) { uid = UUID.randomUUID().toString(); sql = "insert into ts_customer(identity,type,create_time) values(?,?,?)"; ps = conn.prepareStatement(sql); ps.setString(1, uid); ps.setInt(2, 1);// 客户类型,0:路人、1:已存在客户 ps.setString(3, DateFormat.getNowDate()); // 添加客户 ps.executeUpdate(); if (toMail != null && !toMail.equals("null")) { sql = "select count(*) from ts_customer_email where identity = ? and email = ?"; ps = conn.prepareStatement(sql); ps.setString(1, uid); ps.setString(2, toMail); rs = ps.executeQuery(); if (rs.first()) { count = rs.getLong(1); } if (count == 0L) { sql = "insert into ts_customer_email(identity,email,create_time) values(?,?,?)"; ps = conn.prepareStatement(sql); ps.setString(1, uid); ps.setString(2, toMail); ps.setString(3, DateFormat.getNowDate()); // 添加email ps.executeUpdate(); } } } } else { String ems = ""; if (emails.size() > 0) {// 浏览器里有邮箱 for (String email : emails) { ems += ",'" + email + "'"; } if (StringUtils.isNotEmpty(param.getString("ywxMail"))) { ems += ",'" + param.getString("ywxMail") + "'"; } if (ems.trim().length() > 0) { ems = ems.substring(1); linkInfo = WebmailDBUtil.getUserEmail(userId, companyId, ems); toMail = String.valueOf(linkInfo.get("email")); if (ywxType != 8 && linkInfo.get("userId") != null) { userId = Integer.valueOf(linkInfo.get("userId") .toString()); } } // 浏览器有客户邮箱且数据没有保存,则保存 if (toMail != null && !toMail.equals("null")) { sql = "select count(*) from ts_customer_email where identity = ? and email = ?"; ps = conn.prepareStatement(sql); ps.setString(1, uid); ps.setString(2, toMail); rs = ps.executeQuery(); if (rs.first()) { count = rs.getLong(1); } if (count == 0L) { sql = "insert into ts_customer_email(identity,email,create_time) values(?,?,?)"; ps = conn.prepareStatement(sql); ps.setString(1, uid); ps.setString(2, toMail); ps.setString(3, DateFormat.getNowDate()); // 添加email ps.executeUpdate(); } } } else {// 浏览器里没有邮箱 sql = "select email from ts_customer_email where identity = ?"; ps = conn.prepareStatement(sql); ps.setString(1, uid); rs = ps.executeQuery(); while (rs.next()) { ems += ",'" + rs.getString("email") + "'"; } if (StringUtils.isNotEmpty(param.getString("ywxMail"))) { ems += ",'" + param.getString("ywxMail") + "'"; } if (ems.trim().length() > 0) { ems = ems.substring(1); linkInfo = WebmailDBUtil.getUserEmail(userId, companyId, ems); toMail = String.valueOf(linkInfo.get("email")); if (ywxType != 8 && linkInfo.get("userId") != null) { userId = Integer.valueOf(linkInfo.get("userId") .toString()); } } } } if ((toMail == null || toMail.trim().isEmpty() || toMail .equals("null")) && StringUtils.isNotEmpty(param.getString("ywxMail"))) { toMail = param.getString("ywxMail"); } if (toMail != null && !toMail.equals("null") && !emails.contains(toMail)) { emails.add(toMail); } // 数据组装 String agentString = param.getString("agentString"); String referer = param.getString("referer"); String fromDomain = null; if (referer != null && !referer.trim().isEmpty()) { try { referer = URLDecoder.decode(referer, "UTF-8"); fromDomain = new URL(referer).getHost(); } catch (Exception e) { System.err.println("referer域名解析失败:" + e.getClass().getName() + (e.getMessage() == null ? "" : ("->" + e .getMessage()))); } } String language = param.getString("language"); String country2 = param.getString("country"); if (country2 != null && !country2.trim().isEmpty()) { language += "-" + country2; } String accessUrl = param.getString("ywxTo"); String accessDomain = null; if (accessUrl != null) { try { accessUrl = URLDecoder.decode(accessUrl, "UTF-8"); accessDomain = new URL(accessUrl).getHost(); } catch (Exception e) { System.err.println("ywxTo域名解析失败:" + e.getClass().getName() + (e.getMessage() == null ? "" : ("->" + e .getMessage()))); } } // 解析ip String url = controlCentreUrl + "/webservice/ip"; Map<String, Object> params = new HashMap<String, Object>(); params.put("ip", ip); String continent = null; String country = null; String province = null; String city = null; String address = null; String netProvider = null; JSONObject areaJson = null; Map<String, Object> result = HttpUtil.doGet(url, params); if (result.get("code").equals(200)) { Object data = result.get("data"); areaJson = JSONObject.fromObject(data); if (areaJson.getInt("code") == 200) { areaJson = JSONObject.fromObject(areaJson.get("result")); netProvider = areaJson.getString("isp"); continent = areaJson.getString("land"); country = areaJson.getString("country"); province = areaJson.getString("prov"); city = areaJson.getString("city"); address = areaJson.getString("dist"); } else { System.err.println("ip解析失败:" + areaJson.get("result")); } } else { System.err.println("ip解析失败:" + result.get("msg")); } UserAgent userAgent = UserAgent .parseUserAgentString(agentString); if (toMail != null && toMail.equals("null")) { toMail = null; } if (toMail == null && emails.size() > 0) { toMail = emails.get(0); } if (userId == null || userId == 0) { // 没有用户id则获取设置id userId = WebmailDBUtil.getUserId(companyId, accessUrl); // 没有用户id则获取管理员id if (userId == 0) { userId = CentreDBUtil.getUserId(companyId); } } if (toMail != null && !toMail.trim().isEmpty()) { if (!emailPattern.matcher(toMail.trim().toLowerCase()) .matches()) { // 邮箱格式错误就放弃添加 System.err.println("邮箱格式错误就放弃添加:" + toMail); return; } } toMail = ywxType == 7 ? param.getString("ywxMail") : toMail; String dbuid = null;// 邮箱在数据库中的第一条记录下的cookie标识 if (toMail != null && !toMail.trim().isEmpty()) { sql = "select identity from ts_customer_access where access_email = ? order by create_time ASC limit 1"; ps = conn.prepareStatement(sql); ps.setString(1, toMail); rs = ps.executeQuery(); if (rs.first()) { dbuid = rs.getString("identity"); } if (dbuid != null && !dbuid.equals(uid)) { uid = dbuid; } } if (toMail != null && !toMail.trim().isEmpty() && !toMail.equalsIgnoreCase("null")) { sql = "select count(*) from ts_customer_email where identity = ? and email = ?"; ps = conn.prepareStatement(sql); ps.setString(1, uid); ps.setString(2, toMail); rs = ps.executeQuery(); if (rs.first()) { count = rs.getLong(1); } if (count == 0L) { sql = "insert into ts_customer_email(identity,email,create_time) values(?,?,?)"; ps = conn.prepareStatement(sql); ps.setString(1, uid); ps.setString(2, toMail); ps.setString(3, DateFormat.getNowDate()); // 添加email ps.executeUpdate(); } } final int customerId = WebmailDBUtil.getCustomerId(userId, toMail); // 添加浏览记录 sql = "insert into ts_customer_access(identity,user_id,company_id,mail_uid,title,from_url,from_domain,access_url,access_domain,ip,jsession_id,continent,country,province,city,address,device_type,browser_name,language,screen_x,screen_y,net_provider,os,search_word,user_agent,cookie_enable,access_time,access_email,res_type,create_time,template_id,customer_id,from_type,count_id,status,is_imap) values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; ps = conn.prepareStatement(sql); ps.setString(1, uid);// cookie唯一标示 ps.setInt(2, userId);// 用户id ps.setInt(3, companyId);// 企业id ps.setString(4, null);// 邮件唯一标示 ps.setString(5, title);// 来源标题 ps.setString(6, referer);// 来源url ps.setString(7, fromDomain);// 来源域名 ps.setString(8, accessUrl);// 受访问url ps.setString(9, accessDomain);// 受访问域名 ps.setString(10, ip);// 客户端ip ps.setString(11, jsessionId);// 回话id ps.setString(12, continent);// 访问者所属洲 ps.setString(13, country);// 访问者所属国际 ps.setString(14, province);// //访问者所属省份 ps.setString(15, city);// //访问者所属城市 ps.setString(16, address);// //访问者所属详细地址 ps.setInt(17, TrackUtil.getDeviceType(userAgent));// 设备类型 ps.setString(18, userAgent.getBrowser().getName());// 浏览器名称 ps.setString(19, language);// 浏览器设置的语言 ps.setInt(20, ywxX);// 设备宽度 ps.setInt(21, ywxH);// 设备高度 ps.setString(22, netProvider);// 网络接入商 ps.setString(23, userAgent.getOperatingSystem().getName());// 操作系统名称 ps.setString(24, TrackUtil.getSearchWord(referer));// 搜索词 ps.setString(25, agentString);// 浏览器ua ps.setInt(26, cookieEnabled ? 1 : 0);// 是否支持cookie,1支持、0不支持 ps.setInt(27, 0);// 访问时长,单位毫秒 ps.setString(28, toMail);// 客户邮箱 ps.setInt(29, ywxType);// 受访问资源类型,0营销邮邮件、1营销邮邮件HTML页面、2易外销用户站点、3营销邮邮件里需要跟踪的超链、4营销邮邮件HTML页面里需要跟踪的超链、5易外销邮件、6易外销邮件里需要跟踪的超链、7询盘 ps.setString(30, DateFormat.getNowDate());// 创建时间 ps.setInt(31, templateId);// 模板id ps.setInt(32, customerId);// 客户id ps.setInt(33, TrackUtil.getFromType(referer));// 来源类别,-1无来源url、0:外链、1社交、2搜索、3邮件 ps.setLong(34, 0L);// 统计id ps.setInt(35, 1);// 状态,0删除、1正常 ps.setInt(36, Integer.valueOf(poporimap));// 是否是imap邮件,0否、1是 // 提交添加 ps.executeUpdate(); // 获取自动生成的id rs = ps.getGeneratedKeys(); long id = 0L; if (rs.first()) { id = rs.getLong(1); } sql = "select id,create_time from ts_customer_access where id != ? and identity = ? and user_id = ? and company_id = ? and to_days(create_time) = to_days(now()) order by create_time desc"; ps = conn.prepareStatement(sql); ps.setLong(1, id); ps.setString(2, uid); ps.setInt(3, userId); ps.setInt(4, companyId); // 有上一条记录则修改上一条记录的访问时长 rs = ps.executeQuery(); if (rs.first()) { long milliSeconds = DateFormat.milliSeconds( rs.getString("create_time"), DateFormat.getNowDate()); if (milliSeconds < (1000 * 60 * 60 * 2)) {// 当天前后两个请求大于2个小时的丢掉 sql = "update ts_customer_access set access_time = ? where id = ?"; ps = conn.prepareStatement(sql); ps.setLong(1, milliSeconds); ps.setLong(2, rs.getLong("id")); // 修改上一个请求的访问时长 ps.executeUpdate(); } } final JSONObject areaJson2 = areaJson; final int recordType = ywxType; final long recordId = id; final String recordEmail = toMail; final String recordLink = (accessUrl == null ? null : URLDecoder.decode(accessUrl, "UTF-8")); final int recordUserId = userId; final int recordTemplateId = templateId; System.out.println("ok..."); // 点击超链接时异步添加消息提醒:4营销邮邮件HTML页面里需要跟踪的超链 if ((recordLink != null && !recordLink.trim().isEmpty()) && (recordType == 2 || recordType == 4)) { fixedThreadPool.execute(new Runnable() { public void run() { System.out.println("开始添加消息提醒,recordType:" + recordType); if (recordType == 2) { String chatType = "Unknown"; if (recordLink.startsWith("skype:live:")) { chatType = "Skype"; } else if (recordLink.startsWith("https://api.whatsapp.com/send")) { chatType = "WhatAPP"; } else if (recordLink.startsWith("http://wpa.qq.com/msgrd")) { chatType = "QQ"; } else if (recordLink.startsWith("http://amos.alicdn.com/msg.aw")) { chatType = "阿里旺旺"; } if (!chatType.equals("Unknown")) { System.out.println("开始添加页面在线咨询超链点击消息提醒..."); String name = null; if (customerId > 0) { name = WebmailDBUtil.getCustomerName(customerId); } if (name == null || name.trim().isEmpty()) { name = "新访客"; } String area = ""; if (areaJson2 != null && areaJson2.containsKey("country")) { String country2 = areaJson2.getString("country"); if (country2 != null && !country2.trim().isEmpty()) { area += country2; } String province2 = areaJson2.getString("prov"); if (province2 != null && !province2.trim().isEmpty()) { area += province2; } String city2 = areaJson2.getString("city"); if (city2 != null && !city2.trim().isEmpty()) { area += city2; } } if (area.isEmpty()) { area = "未知地区"; } Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; try { conn = WebmailDBUtil.getConnection(); //张三@@espeed@@美国@@espeed@@Skype String content = name + "@@espeed@@" + area + "@@espeed@@" + chatType; String sql = "insert into sys_user_remind(remind_userid,remind_type,remind_status,remind_time,remind_content,target_id,is_read) values(?,?,?,?,?,?,?)"; ps = conn.prepareStatement(sql); ps.setObject(1, recordUserId); ps.setObject(2, 32); ps.setObject(3, 0); ps.setObject(4, DateFormat.getNowDate()); ps.setObject(5, content); ps.setObject(6, recordId); ps.setObject(7, 0); ps.executeUpdate(); System.out.println("消息提醒添加完成"); } catch (Exception e) { e.printStackTrace(); } finally { WebmailDBUtil.close(rs, ps, conn); } } } else if (recordType == 4 && recordEmail != null && !recordEmail.trim().isEmpty()) { System.out.println("开始添加营销邮页面超链点击消息提醒..."); String title = null; Map<String, Object> templateInfo = YxyDBUtil .getTemplateInfo(recordTemplateId); if (!templateInfo.get("code").equals(200)) { System.err.println("获取模板信息失败:" + templateInfo.get("msg")); //return; } else { title = String.valueOf(templateInfo.get("subject")); } if (title == null || title.trim().isEmpty()) { title = "未知"; } Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; try { //一个封邮件里的一个超链接一天提醒一次 // 《xx》邮箱点开了您邮件/模板《xx》里的超链接《xx》 conn = WebmailDBUtil.getConnection(); String sql = "select id from sys_user_remind where to_days(remind_time) = to_days(now()) and remind_content like '《" + recordEmail.trim() + "》%点开了您模板《" + title.trim() + "》%超链接《" + recordLink.trim() + "》%' and remind_userid = " + recordUserId; ps = conn.prepareStatement(sql); rs = ps.executeQuery(); int id = 0; if (rs.first()) { id = rs.getInt("id"); } if (id == 0) { String content = "《"+recordEmail.trim()+"》邮箱点开了您模板《"+title.trim()+"》里的超链接《"+recordLink.trim()+"》,请前往追踪统计查看!"; sql = "insert into sys_user_remind(remind_userid,remind_type,remind_status,remind_time,remind_content,target_id,is_read) values(?,?,?,?,?,?,?)"; ps = conn.prepareStatement(sql); ps.setObject(1, recordUserId); ps.setObject(2, 21); ps.setObject(3, 0); ps.setObject(4, DateFormat.getNowDate()); ps.setObject(5, content); ps.setObject(6, recordId); ps.setObject(7, 0); ps.executeUpdate(); System.out.println("消息提醒添加完成"); } } catch (Exception e) { e.printStackTrace(); } finally { WebmailDBUtil.close(rs, ps, conn); } } } }); } // try的最后提交事务 conn.commit(); } else { System.err.println("无法获取ip"); } } catch (Exception e) { if (conn != null) { try { // 回滚事务 conn.rollback(); } catch (SQLException ex) { ex.printStackTrace(); } } e.printStackTrace(); LogUtil.saveInfoLog(param.getString("ywxType") + "/" + userId, e); } finally { DBUtil.close(rs, ps, conn); } } /** 重新组装cookie */ public static Map<String, String> getCookieMap(Cookie[] cookies) { Map<String, String> resultMap = new HashMap<String, String>(); for (Cookie cookie : cookies) { resultMap.put(cookie.getName(), cookie.getValue()); } return resultMap; } /** 获取浏览器设备类型 */ public static int getDeviceType(UserAgent userAgent) { int type = 0; if (userAgent != null) { String name = userAgent.getOperatingSystem().getDeviceType() .getName(); // 访问者设备类型,0:pc、1:手机、2:平板、3:其他 if (name.equals("Computer")) { type = 0; } else if (name.equals("Mobile")) { type = 1; } else if (name.equals("Tablet")) { type = 2; } else { type = 3; } } return type; } /** 获取来源url中带有的搜索词 */ public static String getSearchWord(String referer) { String searchWord = null; if (referer != null && !referer.trim().isEmpty()) { referer = referer.toLowerCase(); if (referer.contains("baidu.com") && (referer.contains("wd=") || referer.contains("word="))) {// 百度 if (referer.contains("wd=")) { referer = referer.split("wd=")[1]; } else if (referer.contains("word=")) { referer = referer.split("word=")[1]; } if (referer.contains("&")) { searchWord = referer.split("&")[0]; } else { searchWord = referer; } } else if (referer.contains("so.com") && referer.contains("q=")) {// 360 referer = referer.split("q=")[1]; if (referer.contains("&")) { searchWord = referer.split("&")[0]; } else { searchWord = referer; } } else if (referer.contains("sogou.com") && (referer.contains("query=") || referer .contains("keyword="))) {// 搜狗 if (referer.contains("query=")) { referer = referer.split("query=")[1]; } else if (referer.contains("keyword=")) { referer = referer.split("keyword=")[1]; } if (referer.contains("&")) { searchWord = referer.split("&")[0]; } else { searchWord = referer; } } else if (referer.contains("google.com") && referer.contains("q=")) {// 谷歌 referer = referer.split("q=")[1]; if (referer.contains("&")) { searchWord = referer.split("&")[0]; } else { searchWord = referer; } } else if (referer.contains("bing.com") && referer.contains("q=")) {// 必应 referer = referer.split("q=")[1]; if (referer.contains("&")) { searchWord = referer.split("&")[0]; } else { searchWord = referer; } } else if (referer.contains("yahoo.com") && referer.contains("p=")) {// 雅虎 referer = referer.split("p=")[1]; if (referer.contains("&")) { searchWord = referer.split("&")[0]; } else { searchWord = referer; } } } if (searchWord != null) { try { searchWord = URLDecoder.decode(searchWord, "UTF-8"); } catch (UnsupportedEncodingException e) { } } return searchWord; } /** 统计邮件里的超链 */ public static void countLink(Integer userId, Integer companyId, String mailUid, String url, String email, Long aid) { if (url == null || url.trim().isEmpty()) { return; } url = url.trim(); Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; try { conn = DBUtil.getConnection(); conn.setAutoCommit(false);// 开启事务 long id = 0L; String sql = "select id from ts_count_link where user_id = ? and company_id = ? and mail_uid = ? and url = ? and email = ?"; ps = conn.prepareStatement(sql); ps.setInt(1, userId); ps.setInt(2, companyId); ps.setString(3, mailUid); ps.setString(4, url); ps.setString(5, email); rs = ps.executeQuery(); if (rs.first()) { id = rs.getLong("id"); } if (id > 0L) { sql = "update ts_count_link set count = count + 1 where id = ?"; ps = conn.prepareStatement(sql); ps.setLong(1, id); ps.executeUpdate(); } else { sql = "insert into ts_count_link(user_id,company_id,mail_uid,url,email,count) values(?,?,?,?,?,?)"; ps = conn.prepareStatement(sql); ps.setInt(1, userId); ps.setInt(2, companyId); ps.setString(3, mailUid); ps.setString(4, url); ps.setString(5, email); ps.setInt(6, 1); ps.executeUpdate(); // 获取自动生成的id rs = ps.getGeneratedKeys(); if (rs.first()) { id = rs.getLong(1); } } sql = "update ts_customer_access set count_id = ? where id = ?"; ps = conn.prepareStatement(sql); ps.setLong(1, id); ps.setLong(2, aid); ps.executeUpdate(); // try的最后提交事务 conn.commit(); } catch (Exception e) { if (conn != null) { try { // 回滚事务 conn.rollback(); } catch (SQLException ex) { ex.printStackTrace(); } } e.printStackTrace(); } finally { DBUtil.close(rs, ps, conn); } } /** 获取来源类别,-1无来源url、0:外链、1社交、2搜索、3邮件 */ public static int getFromType(String fromUrl) { int type = -1; if (fromUrl != null) { String domain = null; try { domain = new URL(fromUrl).getHost(); } catch (Exception e) { } if (domain != null) { if (!ipPattern.matcher(domain).matches()) { FromRequest from = FromRequest.getFrom(domain); if (from != null) { type = from.getType(); } else { type = 0; } } else { type = 0; } } } return type; } public static Map<String, Object> changeStatus(String ids, Integer status) { Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; Map<String, Object> resultMap = new HashMap<String, Object>(); if (ids == null || ids.trim().isEmpty()) { resultMap.put("code", 400); resultMap.put("success", false); resultMap.put("msg", "id不能为空"); return resultMap; } if (status == null) { resultMap.put("code", 400); resultMap.put("success", false); resultMap.put("msg", "状态值不能为空"); return resultMap; } try { conn = DBUtil.getConnection(); conn.setAutoCommit(false);// 开启事务 String sql = "update ts_customer_access set status = ? where id in(" + StringEscapeUtils.escapeSql(ids) + ")"; ps = conn.prepareStatement(sql); if (status == 1) { ps.setInt(1, 1); } else if (status == 0) { ps.setInt(1, 0); } ps.executeUpdate(); // try的最后提交事务 conn.commit(); resultMap.put("code", 200); resultMap.put("success", true); resultMap.put("msg", ConstantUtil.SUCCESS); } catch (Exception e) { if (conn != null) { try { // 回滚事务 conn.rollback(); } catch (SQLException ex) { ex.printStackTrace(); } } resultMap.put("success", false); resultMap.put("code", 500); resultMap.put( "msg", "异常:" + e.getClass().getName() + (e.getMessage() == null ? "" : ("->" + e .getMessage()))); } finally { DBUtil.close(rs, ps, conn); } return resultMap; } public static Map<String, Object> updateCustomerIds(Long id, Integer customerId) { Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; Map<String, Object> resultMap = new HashMap<String, Object>(); if (id == null) { resultMap.put("code", 400); resultMap.put("success", false); resultMap.put("msg", "id不能为空"); return resultMap; } if (customerId == null) { resultMap.put("code", 400); resultMap.put("success", false); resultMap.put("msg", "客户id不能为空"); return resultMap; } try { conn = DBUtil.getConnection(); conn.setAutoCommit(false);// 开启事务 String sql = "select user_id,access_email from ts_customer_access where id = ?"; ps = conn.prepareStatement(sql); ps.setLong(1, id); rs = ps.executeQuery(); if (!rs.first()) { resultMap.put("code", 400); resultMap.put("success", false); resultMap.put("msg", "不存在该id"); return resultMap; } if (rs.getString("access_email") != null && !rs.getString("access_email").trim().isEmpty()) { sql = "update ts_customer_access set customer_id = ? where user_id = ? and access_email = ?"; ps = conn.prepareStatement(sql); ps.setInt(1, customerId); ps.setInt(2, rs.getInt("user_id")); ps.setString(3, rs.getString("access_email")); ps.executeUpdate(); } // try的最后提交事务 conn.commit(); resultMap.put("code", 200); resultMap.put("success", true); resultMap.put("msg", ConstantUtil.SUCCESS); } catch (Exception e) { if (conn != null) { try { // 回滚事务 conn.rollback(); } catch (SQLException ex) { ex.printStackTrace(); } } resultMap.put("success", false); resultMap.put("code", 500); resultMap.put( "msg", "异常:" + e.getClass().getName() + (e.getMessage() == null ? "" : ("->" + e .getMessage()))); } finally { DBUtil.close(rs, ps, conn); } return resultMap; } public static List<Map<String, Object>> getRecordInfos(Long id) { List<Map<String, Object>> list = new ArrayList<Map<String, Object>>(); if (id == null) { return list; } Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; ResultSetMetaData metaData = null; int count = 0; try { conn = DBUtil.getConnection(); String sql = "select id,user_id,company_id,mail_uid,access_url,access_email,ip,country,province,city,user_agent,create_time from ts_customer_access where res_type =3 and id > ? limit ?"; ps = conn.prepareStatement(sql); ps.setLong(1, id); ps.setInt(2, 200); rs = ps.executeQuery(); String name = null; Map<String, Object> recordMap = null; while (rs.next()) { metaData = rs.getMetaData(); count = metaData.getColumnCount(); if (count > 0) { recordMap = new HashMap<String, Object>(); for (int i = 1; i <= count; i++) { name = metaData.getColumnName(i); recordMap.put(name, rs.getObject(name)); } list.add(recordMap); } } } catch (Exception e) { e.printStackTrace(); } finally { DBUtil.close(rs, ps, conn); } return list; } public static Map<String, Object> getUserId(String token) { Map<String, Object> resultMap = new HashMap<String, Object>(); resultMap.put("code", 300); resultMap.put("success", false); resultMap.put("msg", "token缺失或者格式错误或已过期"); if (token != null && !token.trim().isEmpty()) { try { // 解析token Claims claims = Jwts.parser().setSigningKey(secretkey) .parseClaimsJws(token).getBody(); resultMap.put("code", 200); resultMap.put("success", true); resultMap.put("msg", ConstantUtil.SUCCESS); resultMap.put("data", claims.get("user_id", Integer.class)); } catch (Exception e) { e.printStackTrace(); } } return resultMap; } }