首先写个注解类,用来标识方法满足切入点

package com.enation.framework.database;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;  /** * 表示对标记有xxx注解的类,做代理 注解@Retention可以用来修饰注解,是注解的注解,称为元注解。 * Retention注解有一个属性value,是RetentionPolicy类型的,Enum RetentionPolicy是一个枚举类型, * 这个枚举决定了Retention注解应该如何去保持,也可理解为Rentention 搭配 * RententionPolicy使用。RetentionPolicy有3个值:CLASS RUNTIME SOURCE * 用@Retention(RetentionPolicy * .CLASS)修饰的注解,表示注解的信息被保留在class文件(字节码文件)中当程序编译时,但不会被虚拟机读取在运行的时候; * 用@Retention(RetentionPolicy.SOURCE * )修饰的注解,表示注解的信息会被编译器抛弃,不会留在class文件中,注解的信息只会留在源文件中; * 用@Retention(RetentionPolicy.RUNTIME * )修饰的注解,表示注解的信息被保留在class文件(字节码文件)中当程序编译时,会被虚拟机保留在运行时, * 所以他们可以用反射的方式读取。RetentionPolicy.RUNTIME * 可以让你从JVM中读取Annotation注解的信息,以便在分析程序的时候使用. *  * 类和方法的annotation缺省情况下是不出现在javadoc中的,为了加入这个性质我们用@Documented *  java用  @interface Annotation{ } 定义一个注解 @Annotation,一个注解是一个类。 *  @interface是一个关键字,在设计annotations的时候必须把一个类型定义为@interface,而不能用class或interface关键字  *  * @author daizequn*  */  @Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MethodLog {  String remark() default "";  String operType() default "0";     // String desc() default "";
}

用户日志实体

package com.enation.app.shop.core.model;
import com.enation.framework.database.DynamicField;
import com.enation.framework.database.PrimaryKeyField;
/*** 用户日志实体* @author daizequn  * 2015-12-2*/
public class Log extends DynamicField {private Integer log_id;//主键IDprivate Integer member_id;//用户idprivate String member_uname;//用户账号private String member_name;//用户昵称private String method;//操作方法private String methodargs;//方法参数(暂时不用到)private String allmethod;//完整操作方法private String html;//操作页面private String des;//操作描述private String ipaddr;//操作ip private String pointkey;//搜索关键词private Long staytime;//停留时间private String opentime;//打开页面时间private String closetime;//关闭页面时间@PrimaryKeyFieldpublic Integer getLog_id() {return log_id;}public void setLog_id(Integer log_id) {this.log_id = log_id;}public Integer getMember_id() {return member_id;}public void setMember_id(Integer member_id) {this.member_id = member_id;}public String getMember_uname() {return member_uname;}public void setMember_uname(String member_uname) {this.member_uname = member_uname;}public String getMember_name() {return member_name;}public void setMember_name(String member_name) {this.member_name = member_name;}public String getMethod() {return method;}public void setMethod(String method) {this.method = method;}public String getMethodargs() {return methodargs;}public void setMethodargs(String methodargs) {this.methodargs = methodargs;}public String getHtml() {return html;}public void setHtml(String html) {this.html = html;}public String getDes() {return des;}public void setDes(String des) {this.des = des;}public String getIpaddr() {return ipaddr;}public void setIpaddr(String ipaddr) {this.ipaddr = ipaddr;}public String getPointkey() {return pointkey;}public void setPointkey(String pointkey) {this.pointkey = pointkey;}public Long getStaytime() {return staytime;}public void setStaytime(Long staytime) {this.staytime = staytime;}public String getOpentime() {return opentime;}public void setOpentime(String opentime) {this.opentime = opentime;}public String getAllmethod() {return allmethod;}public void setAllmethod(String allmethod) {this.allmethod = allmethod;}public String getClosetime() {return closetime;}public void setClosetime(String closetime) {this.closetime = closetime;}
}

  

在spring的xml文件上加上

<!-- 用户日志 --><bean id="logManager" class="com.enation.app.shop.core.service.impl.LogManager"  parent="baseSupport" />

用户日志接口

package com.enation.app.shop.core.service;
import com.enation.app.shop.core.model.Log;
import com.enation.framework.database.Page;/*** 用户日志接口* 2015-12-2*/
public interface ILogManager {/*** 添加一个用户日志* @param log* @return*/public int add(Log log);/*** 用户行为日志数据* daizequn 2015-12-6*/Page memberBehaviorLogList(int page, int pageSize, String startDate,String endDate, String sortType);}

用户日志实现类

package com.enation.app.shop.core.service.impl;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.enation.app.shop.core.model.Log;
import com.enation.app.shop.core.service.ILogManager;
import com.enation.eop.sdk.database.BaseSupport;
import com.enation.framework.database.Page;/*** 用户日志操作业务实现* @author daizequn* 2015-12-2*/public class LogManager extends BaseSupport implements ILogManager {/*** 添加用户日志记录*/@Transactional(propagation = Propagation.REQUIRED)public int add(Log log) {this.baseDaoSupport.insert("log", log);Integer logid = this.baseDaoSupport.getLastId("log");log.setLog_id(logid);return logid;}/*** 用户行为日志数据* daizequn 2015-12-6*/@Overridepublic Page memberBehaviorLogList(int page, int pageSize, String startDate, String endDate, String sortType) {// 返回打开页面的时间段内的用户行为日志StringBuffer sql = new StringBuffer();sql.append("SELECT g.* FROM es_log g WHERE 1=1 ");if(startDate!=null&&!"".equals(startDate)){sql.append(" and g.opentime>= '"+startDate+"'");}if(endDate!=null&&!"".equals(endDate)){sql.append(" and g.closetime<= '"+endDate+"'");}if(sortType != null && ("ASC".equals(sortType) || "DESC".equals(sortType))){sql.append(" ORDER BY g.opentime " + sortType + " ");}else{sql.append(" ORDER BY g.opentime DESC ");}return this.baseDaoSupport.queryForPage(sql.toString(), page, pageSize, Log.class);}}

 在spring的xml文件上加上

<bean id="logAction" class="com.enation.app.shop.core.action.api.LogAction" scope="prototype"/>

package com.enation.app.shop.core.action.api;
import java.lang.reflect.Method;
import java.util.Date;
import javax.servlet.http.HttpServletRequest;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import com.enation.app.base.core.model.Member;
import com.enation.app.shop.core.model.Log;
import com.enation.app.shop.core.service.impl.LogManager;
import com.enation.app.shop.core.utils.DateUtils;
import com.enation.app.shop.core.utils.IpUtils;
import com.enation.eop.sdk.context.UserConext;
import com.enation.framework.context.spring.SpringContextHolder;
import com.enation.framework.context.webcontext.ThreadContextHolder;
import com.enation.framework.database.MethodLog;
/** * \ *  * @Aspect 实现spring aop 切面(Aspect): *         一个关注点的模块化,这个关注点可能会横切多个对象。事务管理是J2EE应用中一个关于横切关注点的很好的例子。 在Spring *         AOP中,切面可以使用通用类(基于模式的风格) 或者在普通类中以 @Aspect 注解(@AspectJ风格)来实现。 *  *         AOP代理(AOP Proxy): AOP框架创建的对象,用来实现切面契约(aspect contract)(包括通知方法执行等功能)。 *         在Spring中,AOP代理可以是JDK动态代理或者CGLIB代理。 注意:Spring *         2.0最新引入的基于模式(schema-based *         )风格和@AspectJ注解风格的切面声明,对于使用这些风格的用户来说,代理的创建是透明的。 * @author q *  */
@Component
@Aspect
public class LogAction {  /*@Autowired  private ILogManager manager;  */public LogAction() {  System.out.println("Aop");  }  /** * 在Spring * 2.0中,Pointcut的定义包括两个部分:Pointcut表示式(expression)和Pointcut签名(signature * )。让我们先看看execution表示式的格式: * 括号中各个pattern分别表示修饰符匹配(modifier-pattern?)、返回值匹配(ret * -type-pattern)、类路径匹配(declaring * -type-pattern?)、方法名匹配(name-pattern)、参数匹配((param * -pattern))、异常类型匹配(throws-pattern?),其中后面跟着“?”的是可选项。 *  * @param point * @throws Throwable */  @Pointcut("@annotation(com.enation.framework.database.MethodLog)")  public void methodCachePointcut() {  }  // // @Before("execution(* com.wssys.controller.*(..))")  // public void logAll(JoinPoint point) throws Throwable {  // System.out.println("打印========================");  // }  //  // // @After("execution(* com.wssys.controller.*(..))")  // public void after() {  // System.out.println("after");  // }  // 方法执行的前后调用  // @Around("execution(* com.wssys.controller.*(..))||execution(* com.bpm.*.web.account.*.*(..))")  // @Around("execution(* com.wssys.controller.*(..))")  // @Around("execution(* org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(..))")  //@Around("methodCachePointcut()") //@Around("execution(* com.enation.app.shop.core.action.api.*(..))")  @Around("methodCachePointcut()")  public Object commit(ProceedingJoinPoint point) throws Throwable {  Member member = UserConext.getCurrentMember();Object object = null;  if(member!=null){HttpServletRequest request = ThreadContextHolder.getInstance().getHttpRequest();String opentime=DateUtils.date2Str(new Date(), "yyyy-MM-dd HH:mm:ss");//操作时间String ipaddr = IpUtils.getRemoteAddr(request);//操作ipInteger memberid;//用户idString memberuname;//用户账号  String membername; //用户账号memberid=member.getMember_id();memberuname = member.getUname();  membername = member.getName();String monthRemark = getMthodRemark(point);  String monthName = point.getSignature().getName();  String packages = point.getThis().getClass().getName();  if (packages.indexOf("$$EnhancerBySpringCGLIB$$") > -1) { // 如果是CGLIB动态生成的类  try {packages = packages.substring(0, packages.indexOf("$$"));  } catch (Exception ex) {  ex.printStackTrace();  }  }  //        Object[] method_param = null;
//
//        Object object;
//        try {
//            method_param = point.getArgs(); //获取方法参数
//            // String param=(String) point.proceed(point.getArgs());  object = point.proceed();
//        } catch (Exception e) {
//            // 异常处理记录日志..log.error(e);
//            throw e;
//        }  Log log = new Log();  log.setIpaddr(ipaddr);//操作ip log.setMember_id(memberid);//用户idlog.setMember_uname(memberuname);//用户账号log.setMember_name(membername);//用户昵称log.setMethod(packages + "." + monthName); //操作方法log.setDes(monthRemark); //操作描述log.setOpentime(opentime);//操作时间HttpServletRequest httpRequest=(HttpServletRequest)request;  String strBackUrl = "http://" + request.getServerName() //服务器地址  + ":"   + request.getServerPort()           //端口号  + httpRequest.getContextPath()      //项目名称  + httpRequest.getServletPath()      //请求页面或其他地址  + "?" + (httpRequest.getQueryString()); //参数  log.setAllmethod(strBackUrl);//完整操作方法//这里有点纠结 就是不好判断第一个object元素的类型 只好通过  方法描述来 做一一  转型感觉 这里 有点麻烦 可能是我对 aop不太了解  希望懂的高手给予我指点  //有没有更好的办法来记录操作参数  因为参数会有 实体类 或者javabean这种参数怎么把它里面的数据都解析出来?
//        if ("删除商品".equals(monthRemark)) {  Member  member2 = (Member) method_param[0];
//          String method_paramArr="";
//            if(method_param.length!=0){
//              for(int i=0;i<=method_param.length;i++){
//                  method_paramArr=method_paramArr+method_param[i];
//              }
//              log.setMethodargs(method_paramArr);
//            }else{
//              log.setMethodargs("方法无参(不代表前台没传参数过来)");
//            }
//        } else {  log.setMethodargs("操作参数:" + method_param[0]);
//        }  LogManager manager = SpringContextHolder.getBean("logManager");manager.add(log);return object;}return point.proceed();}  // 方法运行出现异常时调用    // @AfterThrowing(pointcut = "execution(* com.wssys.controller.*(..))",  // throwing = "ex")  public void afterThrowing(Exception ex) {  System.out.println("afterThrowing");  System.out.println(ex);  }  // 获取方法的中文备注____用于记录用户的操作日志描述  public static String getMthodRemark(ProceedingJoinPoint joinPoint)  throws Exception {  String targetName = joinPoint.getTarget().getClass().getName();  String methodName = joinPoint.getSignature().getName();  Object[] arguments = joinPoint.getArgs();  Class targetClass = Class.forName(targetName);  Method[] method = targetClass.getMethods();  String methode = "";  for (Method m : method) {  if (m.getName().equals(methodName)) {  Class[] tmpCs = m.getParameterTypes();  if (tmpCs.length == arguments.length) {  MethodLog methodCache = m.getAnnotation(MethodLog.class);  if (methodCache != null) {  methode = methodCache.remark();  }  break;  }  }  }  return methode;  }  }

LogtimeAction

package com.enation.app.shop.core.action.api;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import com.enation.app.base.core.model.Member;
import com.enation.app.shop.core.model.Log;
import com.enation.app.shop.core.service.impl.LogManager;
import com.enation.app.shop.core.utils.DateUtils;
import com.enation.app.shop.core.utils.IpUtils;
import com.enation.eop.sdk.context.UserConext;
import com.enation.framework.action.WWAction;
import com.enation.framework.context.spring.SpringContextHolder;
import com.enation.framework.context.webcontext.ThreadContextHolder;
/*** * * @author Daizequn */
@Component
@Scope("prototype")
@ParentPackage("eop_default")
@Namespace("/api/shop")
@Action("logtime")
@SuppressWarnings({ "rawtypes", "unchecked", "serial", "static-access" })
public class LogtimeAction extends WWAction {private String html;private String opentime;private String closetime;public String addLogtime() {Member member=UserConext.getCurrentMember();if(member!=null&&opentime!=null&&closetime!=null&&!closetime.equals(opentime)){this.showSuccessJson("成功关闭");Integer memberid;String memberuname;  String membername; String pointkey;HttpServletRequest request = ThreadContextHolder.getInstance().getHttpRequest();HttpServletRequest httpRequest=(HttpServletRequest)request;  String strBackUrl = "http://" + request.getServerName() //服务器地址  + ":"   + request.getServerPort()           //端口号  + httpRequest.getContextPath()      //项目名称  + httpRequest.getServletPath()      //请求页面或其他地址  + "?" + (httpRequest.getQueryString()); //参数  try {strBackUrl=URLDecoder.decode(strBackUrl,"utf-8");} catch (UnsupportedEncodingException e) {e.printStackTrace();}memberid=member.getMember_id();memberuname = member.getUname();  membername = member.getName();String ipaddr = IpUtils.getRemoteAddr(request);//操作IPLog log = new Log();  log.setIpaddr(ipaddr);//操作IPlog.setMember_id(memberid);//用户idlog.setMember_uname(memberuname);//用户账号log.setMember_name(membername);//用户昵称html=html.replace("//www.ZhUiChaGuOji.org/cn/=**://", "");try {html=URLDecoder.decode(html,"utf-8");} catch (UnsupportedEncodingException e1) {e1.printStackTrace();}if(html.contains("search-keyword-")){pointkey=html.substring(html.indexOf("-")+9);pointkey=pointkey.replace(".html", "");log.setPointkey(pointkey);}log.setHtml(html);//操作页面log.setAllmethod(strBackUrl);//完整操作方法log.setClosetime(closetime);//保存关闭时间try {String createtime=DateUtils.getDateStrTime();log.setOpentime(opentime);//保存打开页面时间log.setStaytime(DateUtils.getIntervalSecond(opentime, createtime));//停留时间} catch (Exception e) {e.printStackTrace();}LogManager manager = SpringContextHolder.getBean("logManager");manager.add(log);  }return this.JSON_MESSAGE;}public String getHtml() {return html;}public void setHtml(String html) {this.html = html;}public String getOpentime() {return opentime;}public void setOpentime(String opentime) {this.opentime = opentime;}public String getClosetime() {return closetime;}public void setClosetime(String closetime) {this.closetime = closetime;}}

@MethodLog(remark = "删除商品") 

 

/*** 删除购物车一项* * @param cartid*            :要删除的购物车id,int型,即 CartItem.item_id* * @return 返回json字串 result 为1表示调用成功0表示失败 message 为提示信息* *         {@link CartItem }*/@MethodLog(remark = "删除商品") public String delete() {try {HttpServletRequest request = ThreadContextHolder.getInstance().getHttpRequest();String cartid = request.getParameter("cartid");cartManager.delete(request.getSession().getId(), Integer.valueOf(cartid));this.showSuccessJson("删除成功");} catch (RuntimeException e) {this.logger.error("删除购物项失败", e);this.showErrorJson("删除购物项失败");}return this.JSON_MESSAGE;}

工具类

package com.enation.app.shop.core.utils;import java.text.Format;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;/*** * @author HuangGenFa* @create-Date:2008-3-25* @desc:用于转换日期,和获得当前日期* */public class DateUtils {public DateUtils() {}/*** 日期时间,去掉时间* * @param date*            2008-05-05 12:00:00.0* @return String 如:2008-05-05*/public static String getDateToString(Date date) {String datetime = "";if (date != null) {datetime = date.toString();String writedate[] = datetime.split(" ");datetime = writedate[0];}return datetime;}public static String date2Str(Date date, String fmtDate) {String strRtn = null;if (date == null) {return "";}if (fmtDate.length() == 0) {fmtDate = "yyyy/MM/dd";}Format fmt = new SimpleDateFormat(fmtDate);try {strRtn = fmt.format(date);} catch (Exception e) {// e.printStackTrace();}return strRtn;}/*** 转换日期,格式化形式为yyyy-MM-dd hh:mm:ss的字符串 例如:2008-8-8 8:08:08* * @return Date* @throws Exception* @author CaiMingXi*/public static Date str2Date2mmss(String dateStr) throws Exception {Date date = new Date();SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");date = sdf.parse(dateStr);return date;}/*** dateStr字符串日期转为date* @param dateStr* @return* @throws Exception*/public static Date st2Date(String dateStr) throws Exception {Date date = new Date();SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");date = sdf.parse(dateStr);return date;}/*** 根据日期字符串和转换形式,转换为日期* * @return Date* @throws Exception*/public static Date str2Date(String dateStr, String fmtDate)throws Exception {Date date = new Date();if (fmtDate.length() == 0) {fmtDate = "yyyy-MM-dd";}SimpleDateFormat sdf = new SimpleDateFormat(fmtDate);date = sdf.parse(dateStr);return date;}/*** 得到当前日期,格式化形式为yyyy-MM-dd的字符串* * @throws Exception* @return String*/public static String getDateStr() throws Exception {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");Date now = new Date();String today = sdf.format(now).toString();return today;}/*** 得到当前日期,格式化形式为yyyy-MM-dd的字符串* * @throws Exception* @return String*/public static String getDateStrZ() throws Exception {SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");Date now = new Date();String today = sdf.format(now).toString();return today;}/*** 得到当前日期,格式化形式为yyyy-MM-dd hh:mm:ss的字符串 例如:2008-8-8 8:08:08* * @throws Exception* @author CaiMingXi* @return String*/public static String getDateStrTime() throws Exception {String today = "";try{SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");Date now = new Date();today = sdf.format(now).toString();return today;}catch(Exception ec){ec.printStackTrace();}return today;}/*** ==============================================================================================================================* 将数字日期转换为中文 HuangGenFa 2008-7-12*/private static final String[] NUMBERS = { "O", "一", "二", "三", "四", "五","六", "七", "八", "九" };/** 通过 yyyy-MM-dd 得到中文大写格式 yyyy MM dd 日期 */public static synchronized String toChinese(String str) {StringBuffer sb = new StringBuffer();sb.append(getSplitDateStr(str, 0)).append("年").append(getSplitDateStr(str, 1)).append("月").append(getSplitDateStr(str, 2)).append("日");return sb.toString();}/** 分别得到年月日的大写 默认分割符 "-" */public static String getSplitDateStr(String str, int unit) {// unit是单位 0=年 1=月 2日String[] DateStr = str.split("-");if (unit > DateStr.length)unit = 0;StringBuffer sb = new StringBuffer();for (int i = 0; i < DateStr[unit].length(); i++) {if ((unit == 1 || unit == 2) && Integer.valueOf(DateStr[unit]) > 9) {sb.append(convertNum(DateStr[unit].substring(0, 1))).append("十").append(convertNum(DateStr[unit].substring(1, 2)));break;} else {sb.append(convertNum(DateStr[unit].substring(i, i + 1)));}}if (unit == 1 || unit == 2) {return sb.toString().replaceAll("^一", "").replace("O", "");}return sb.toString();}/** 转换数字为大写 */private static String convertNum(String str) {return NUMBERS[Integer.valueOf(str)];}/** 判断是否是零或正整数 */public static boolean isNumeric(String str) {Pattern pattern = Pattern.compile("[0-9]*");Matcher isNum = pattern.matcher(str);if (!isNum.matches()) {return false;}return true;}/*** @author CaiMingXi 将一个日期字符串转化成Calendar* @return Calendar*/public static Calendar switchStringToCalendar(String sDate) {Date date = switchStringToDate(sDate);Calendar c = Calendar.getInstance();c.setTime(date);return c;}/*** @author CaiMingXi 自定义日期返回相差天数的日期 例 第一个参数 2008-9-6 第二个参数为 7 那么返回值为*         2008-8-30* @param sDate*            日期字符串* @param n*            相差的天数* @return String*/public static String switchStringToDate(String sDate, int n) {Calendar c = switchStringToCalendar(sDate);c.add(Calendar.DAY_OF_MONTH, -n);return "" + c.get(Calendar.YEAR) + "-" + (c.get(Calendar.MONTH) + 1) + "-"+ c.get(Calendar.DATE);}/*** @author CaiMingXi 自定义日期返回相差天数的日期 例 第一个参数 2008-9-6 第二个参数为 7 那么返回值为*         2008-9-13* @param sDate*            日期字符串* @param n*            相差的天数* @return String*/public static String switchStringHToDate(String sDate, int n) {Calendar c = switchStringToCalendar(sDate);c.add(Calendar.DAY_OF_MONTH, +n);return "" + c.get(Calendar.YEAR) + "-" + (c.get(Calendar.MONTH) + 1) + "-"+ c.get(Calendar.DATE);}/*** 返回相差天数的日期* @param date 日期* @param days 天数* @return*/public static Date switchToDate(Date date,int days) {Calendar c = Calendar.getInstance();c.setTime(date);c.add(Calendar.DAY_OF_MONTH,+days);return c.getTime();}/*** 返回相差月数的日期* @param date 日期* @param month 月数* @return*/public static Date switchToMonth(Date date,int month) {Calendar c = Calendar.getInstance();c.setTime(date);c.add(Calendar.MONTH, 1);return c.getTime();}/*** @author CaiMingXi 取得系统当前时间前n天,格式为yyyy-mm-dd* @param n*            相差的天数* @return String*/public static String getNDayBeforeCurrentDate(int n) {Calendar c = Calendar.getInstance();c.add(Calendar.DAY_OF_MONTH, -n);return "" + c.get(Calendar.YEAR) + "-" + (c.get(Calendar.MONTH) + 1) + "-"+ c.get(Calendar.DATE);}/*** @author CaiMingXi 取得系统当前时间后n天,格式为yyyy-mm-dd* @param n*            相差的天数* @return String*/public static String getHDayBeforeCurrentDate(int n) {Calendar c = Calendar.getInstance();c.add(Calendar.DAY_OF_MONTH, +n);return "" + c.get(Calendar.YEAR) + "-" + (c.get(Calendar.MONTH) + 1) + "-"+ c.get(Calendar.DATE);}/*** @author CaiMingXi 输入两个字符串型的日期,比较两者的大小* @return boolean*/public static boolean compareTwoDateBigOrSmall(String fromDate,String toDate) {Date dateFrom = switchStringToDate(fromDate);Date dateTo = switchStringToDate(toDate);if (dateFrom.before(dateTo)) {return true;} else {return false;}}/*** @author CaiMingXi 将一个日期字符串转化成日期* @return Date*/public static Date switchStringToDate(String sDate) {Date date = null;try {SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");date = df.parse(sDate);} catch (Exception e) {// System.out.println("日期转换失败:" + e.getMessage());}return date;}/*** @author CaiMingXi 比较日期返回天数* @return int*/public static int getDifferDays(String strBegin, String strEnd) {SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd");Date date1 = null, date2 = null;int days = 0;try {date1 = f.parse(strBegin);date2 = f.parse(strEnd);days = (int) ((date2.getTime() - date1.getTime()) / 86400000);} catch (Exception e) {// TODO 自动生成 catch 块e.printStackTrace();}return days;}/*** @author ZhaiZhengqiang 比较日期返回天数* @return int*/public static int getDifferDays(Date begin, Date end) {int days = (int)((end.getTime() - begin.getTime()) / 86400000);return days;}public static int getDifferDays2(Date begin, Date end) {SimpleDateFormat smdf = new SimpleDateFormat("yyyy-MM-dd");String start = smdf.format(begin);String end2 = smdf.format(end);int days=getDifferDays(start, end2);return days;}/**   * 计算两个日期之间相差的月数   * @param date1   * @param date2   * @return   */    public static int getMonths(Date date1, Date date2){     int iMonth = 0;     int flag = 0;     try{     Calendar objCalendarDate1 = Calendar.getInstance();     objCalendarDate1.setTime(date1);     Calendar objCalendarDate2 = Calendar.getInstance();     objCalendarDate2.setTime(date2);     if (objCalendarDate2.equals(objCalendarDate1))     return 0;     if (objCalendarDate1.after(objCalendarDate2)){     Calendar temp = objCalendarDate1;     objCalendarDate1 = objCalendarDate2;     objCalendarDate2 = temp;     }     if (objCalendarDate2.get(Calendar.DAY_OF_MONTH) < objCalendarDate1.get(Calendar.DAY_OF_MONTH))     flag = 1;     if (objCalendarDate2.get(Calendar.YEAR) > objCalendarDate1.get(Calendar.YEAR))     iMonth = ((objCalendarDate2.get(Calendar.YEAR) - objCalendarDate1.get(Calendar.YEAR))     * 12 + objCalendarDate2.get(Calendar.MONTH) - flag)     - objCalendarDate1.get(Calendar.MONTH);     else    iMonth = objCalendarDate2.get(Calendar.MONTH)     - objCalendarDate1.get(Calendar.MONTH) - flag;     } catch (Exception e){     e.printStackTrace();     }     return iMonth;     }   private static String HanDigiStr[] = new String[] { "零", "壹", "贰", "叁","肆", "伍", "陆", "柒", "捌", "玖" };private static String HanDiviStr[] = new String[] { "", "拾", "佰", "仟", "万","拾", "佰", "仟", "亿", "拾", "佰", "仟", "万", "拾", "佰", "仟", "亿", "拾","佰", "仟", "万", "拾", "佰", "仟" };/***  输入字符串必须正整数,只允许前导空格(必须右对齐),不宜有前导零* @param NumStr* @return* @author CaiMingXi*/private static String PositiveIntegerToHanStr(String NumStr) { String RMBStr = "";boolean lastzero = false;boolean hasvalue = false; // 亿、万进位前有数值标记int len, n;len = NumStr.length();if (len > 15)return "数值过大!";for (int i = len - 1; i >= 0; i--) {if (NumStr.charAt(len - i - 1) == ' ')continue;n = NumStr.charAt(len - i - 1) - '0';if (n < 0 || n > 9)return "输入含非数字字符!";if (n != 0) {if (lastzero)RMBStr += HanDigiStr[0]; // 若干零后若跟非零值,只显示一个零// 除了亿万前的零不带到后面// if( !( n==1 && (i%4)==1 && (lastzero || i==len-1) ) ) //// 如十进位前有零也不发壹音用此行if (!(n == 1 && (i % 4) == 1 && i == len - 1)) // 十进位处于第一位不发壹音RMBStr += HanDigiStr[n];RMBStr += HanDiviStr[i]; // 非零值后加进位,个位为空hasvalue = true; // 置万进位前有值标记} else {if ((i % 8) == 0 || ((i % 8) == 4 && hasvalue)) // 亿万之间必须有非零值方显示万RMBStr += HanDiviStr[i]; // “亿”或“万”}if (i % 8 == 0)hasvalue = false; // 万进位前有值标记逢亿复位lastzero = (n == 0) && (i % 4 != 0);}if (RMBStr.length() == 0)return HanDigiStr[0]; // 输入空字符或"0",返回"零"return RMBStr;}/** 数字转换大写* @param val* @return 字符串 返回大写字符串* @createDate 2009-4-17*/public static String NumToRMBStr(double val) {String SignStr = "";String TailStr = "";long fraction, integer;int jiao, fen;if (val < 0) {val = -val;SignStr = "负";}if (val > 99999999999999.999 || val < -99999999999999.999)return "数值位数过大!";// 四舍五入到分long temp = Math.round(val * 100);integer = temp / 100;fraction = temp % 100;jiao = (int) fraction / 10;fen = (int) fraction % 10;if (jiao == 0 && fen == 0) {TailStr = "整";} else {TailStr = HanDigiStr[jiao];if (jiao != 0)TailStr += "角";if (integer == 0 && jiao == 0) // 零元后不写零几分TailStr = "";if (fen != 0)TailStr += HanDigiStr[fen] + "分";}// 下一行可用于非正规金融场合,0.03只显示“叁分”而不是“零元叁分”// if( !integer ) return SignStr+TailStr;return "¥" + SignStr + PositiveIntegerToHanStr(String.valueOf(integer))+ "元" + TailStr;}/***  返回乘以10000以后的值* @param val* @return* @author CaiMingXi*/public static String NumToRMBStrW(double val) {String SignStr = "";String TailStr = "";long fraction, integer;int jiao, fen;if (val < 0) {val = -val;SignStr = "负";}if (val > 99999999999999.999 || val < -99999999999999.999)return "数值位数过大!";// 四舍五入到分long temp = Math.round(val * 100);integer = temp / 100;fraction = temp % 100;jiao = (int) fraction / 10;fen = (int) fraction % 10;if (jiao == 0 && fen == 0) {TailStr = "整";} else {TailStr = HanDigiStr[jiao];if (jiao != 0)TailStr += "角";if (integer == 0 && jiao == 0) // 零元后不写零几分TailStr = "";if (fen != 0)TailStr += HanDigiStr[fen] + "分";}// 下一行可用于非正规金融场合,0.03只显示“叁分”而不是“零元叁分”// if( !integer ) return SignStr+TailStr;// 返回乘以10000以后的值return SignStr + PositiveIntegerToHanStr(String.valueOf(integer)) + "元"+ TailStr;}/*** @author dzq 比较日期返回分钟* @return Long*/public static Long getIntervalMini(String strSmall, String strBig) {SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");long date1=0L;long date2=0L;long mini=0L;try {date1 = f.parse(strSmall).getTime();date2=f.parse(strBig).getTime();mini=((date2-date1)/1000);} catch (ParseException e) {e.printStackTrace();}return (mini/60);}/*** @author dzq 比较日期返回分钟* @return Long*/public static Long getIntervalSecond(String strSmall, String strBig) {SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");long date1=0L;long date2=0L;long second=0L;try {date1 = f.parse(strSmall).getTime();date2=f.parse(strBig).getTime();second=((date2-date1)/1000);} catch (ParseException e) {e.printStackTrace();}return (second);}/*** 返回  增加月份后的日期=日期+加上期限(月份数)* @author dzq * @param date 日期* @param expires 期限* @return String*/public static String addExpires(Date date, Integer expires) {Calendar calendar = Calendar.getInstance();calendar.setTime(date);calendar.add(Calendar.MONTH, expires);Date nDate = calendar.getTime(); SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String newDate=f.format(nDate);return newDate;}/*** 返回  增加月份后的日期=日期+加上期限(月份数)* @author dzq * @param date 日期* @param expires 期限* @return Date*/public static Date addExpiresDate(Date date, Integer expires) {Calendar calendar = Calendar.getInstance();calendar.setTime(date);calendar.add(Calendar.MONTH, expires);Date nDate = calendar.getTime(); return nDate;}/*** ==============================================================================================================================*/public static void main(String[] args) {//       String fromDate = "2008-10-6";
//       String toDate = "2008-10-9";
//       Date dateFrom = switchStringToDate(fromDate);
//       Date dateTo = switchStringToDate(toDate);try {// SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
//           int d = getDifferDays2(new Date(),DateUtil.getMonthLastDate(new Date()));
//          System.out.println(getDateStrTime());System.out.println(getIntervalSecond("2015-12-04 10:12:10", "2015-12-05 10:13:10"));} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}
//      System.out.println(DateUtils.getIntervalMini("2011-06-11 08:17:15", "2011-06-13 08:17:15"));}
}

package com.enation.app.shop.core.utils;import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;public class DateUtil {private static final String PATTERN_DATE = "yyyy-MM-dd";private static final String PATTERN_TIME = "HH:mm:ss";private static final String PATTERN_DATETIME = "yyyy-MM-dd HH:mm:ss";private static final String PATTERN_FULL = "yyyy-MM-dd HH:mm:ss.SSS";public static final Date parse(String pattern, String source) {try {return new SimpleDateFormat(pattern, Locale.US).parse(source);} catch (ParseException e) {throw new RuntimeException("parse date error : ", e);}}public static final Date parseDateTime(String source) {try {return new SimpleDateFormat(PATTERN_DATETIME).parse(source);} catch (ParseException e) {throw new RuntimeException("parse date error : ", e);}}public static final Date parseDate(String source) {try {return new SimpleDateFormat(PATTERN_DATE).parse(source);} catch (ParseException e) {throw new RuntimeException("parse date error : ", e);}}public static final Date parseTime(String source) {try {return new SimpleDateFormat(PATTERN_TIME).parse(source);} catch (ParseException e) {throw new RuntimeException("parse date error : ", e);}}public static final Date parseFull(String source) {try {return new SimpleDateFormat(PATTERN_FULL).parse(source);} catch (ParseException e) {throw new RuntimeException("parse date error : ", e);}}public static final String format(String pattern, Date date) {return new SimpleDateFormat(pattern, Locale.US).format(date);}public static final String formatDateTime(Date date) {return new SimpleDateFormat(PATTERN_DATETIME).format(date);}public static final String formatDate(Date date) {return new SimpleDateFormat(PATTERN_DATE).format(date);}public static final String formatTime(Date date) {return new SimpleDateFormat(PATTERN_TIME).format(date);}public static final String formatFull(Date date) {return new SimpleDateFormat(PATTERN_FULL).format(date);}public static final String format(String outPatt, String inPatt, String source) {return format(outPatt, parse(inPatt, source));}public static final String getTimestamp(String pattern) {return format(pattern, new Date());}public static final int calDValueOfYear(Date fromDate, Date toDate) {Calendar sCal = Calendar.getInstance();Calendar eCal = Calendar.getInstance();sCal.setTime(fromDate);eCal.setTime(toDate);return eCal.get(Calendar.YEAR) - sCal.get(Calendar.YEAR);}public static final int calDValueOfMonth(Date fromDate, Date toDate) {Calendar sCal = Calendar.getInstance();Calendar eCal = Calendar.getInstance();sCal.setTime(fromDate);eCal.setTime(toDate);return 12 * (eCal.get(Calendar.YEAR) - sCal.get(Calendar.YEAR)) + (eCal.get(Calendar.MONTH) - sCal.get(Calendar.MONTH));}public static final int calDValueOfDay(Date fromDate, Date toDate) {return (int) ((toDate.getTime() - fromDate.getTime()) / (1000 * 60 * 60 * 24));}public static final Date getFirstDayOfMonth(Date date) {Calendar calendar = Calendar.getInstance();calendar.setTime(date);calendar.set(Calendar.DAY_OF_MONTH, 1);calendar.set(Calendar.HOUR_OF_DAY, 0);calendar.set(Calendar.MINUTE, 0);calendar.set(Calendar.SECOND, 0);calendar.set(Calendar.MILLISECOND, 0);return calendar.getTime();}public static final Date getFirstDayOfWeek(Date date) {return getFirstDayOfWeek(date, Calendar.MONDAY);}public static final Date getLastDayOfWeek(Date date) {return getLastDayOfWeek(date, Calendar.MONDAY);}public static final Date getFirstDayOfWeek(Date date, int firstDayOfWeek) {Calendar calendar = Calendar.getInstance();calendar.setFirstDayOfWeek(firstDayOfWeek);calendar.setTime(date);calendar.set(Calendar.DAY_OF_WEEK, calendar.getFirstDayOfWeek());calendar.set(Calendar.HOUR_OF_DAY, 0);calendar.set(Calendar.MINUTE, 0);calendar.set(Calendar.SECOND, 0);calendar.set(Calendar.MILLISECOND, 0);return calendar.getTime();}public static final Date getLastDayOfWeek(Date date, int firstDayOfWeek) {Calendar calendar = Calendar.getInstance();calendar.setFirstDayOfWeek(firstDayOfWeek);calendar.setTime(date);calendar.set(Calendar.DAY_OF_WEEK, calendar.getFirstDayOfWeek());calendar.set(Calendar.HOUR_OF_DAY, 0);calendar.set(Calendar.MINUTE, 0);calendar.set(Calendar.SECOND, 0);calendar.set(Calendar.MILLISECOND, 0);calendar.add(Calendar.DAY_OF_YEAR, 7);calendar.add(Calendar.MILLISECOND, -1);return calendar.getTime();}public static final Date[] getWeek(Date date) {return getWeek(date, Calendar.MONDAY);}public static final Date[] getWeek(Date date, int firstDayOfWeek) {Calendar calendar = Calendar.getInstance();calendar.setFirstDayOfWeek(firstDayOfWeek);calendar.setTime(date);calendar.set(Calendar.DAY_OF_WEEK, calendar.getFirstDayOfWeek());calendar.set(Calendar.HOUR_OF_DAY, 0);calendar.set(Calendar.MINUTE, 0);calendar.set(Calendar.SECOND, 0);calendar.set(Calendar.MILLISECOND, 0);Date firstDate = calendar.getTime();calendar.add(Calendar.DAY_OF_YEAR, 7);calendar.add(Calendar.MILLISECOND, -1);Date lastDate = calendar.getTime();return new Date[] { firstDate, lastDate };}public static java.sql.Date toSQLDate(Date date) {return new java.sql.Date(date.getTime());}public static java.sql.Date getSQLDate() {return new java.sql.Date(System.currentTimeMillis());}public static java.sql.Timestamp getSQLTimestamp() {return new java.sql.Timestamp(System.currentTimeMillis());}public static java.sql.Timestamp getTimestamp(int day) {return new java.sql.Timestamp(System.currentTimeMillis()+24*60*60*1000*day);}public static Date add(Date date, int field, int increment) {Calendar cal = Calendar.getInstance();cal.setTime(date);cal.add(field, increment);return cal.getTime();}public static Date set(Date date, int field, int value) {Calendar cal = Calendar.getInstance();cal.setTime(date);cal.set(field, value);return cal.getTime();}/*** 当月第一天* @return*/public static Date getMonthFirstDate(){Calendar curCal = Calendar.getInstance();curCal.set(Calendar.DAY_OF_MONTH, 1);return curCal.getTime();}/*** 当月最后一天* @return*/public static Date getMonthLastDate(){Calendar curCal = Calendar.getInstance();curCal.set(Calendar.DATE, 1);  curCal.roll(Calendar.DATE, - 1);  return curCal.getTime();}/*** 当月最后一天* @return*/public static Date getMonthLastDate(Date date){Calendar curCal = Calendar.getInstance();curCal.setTime(date);curCal.set(Calendar.DATE, 1);  curCal.roll(Calendar.DATE, - 1);  return curCal.getTime();}/*** 当月最后一天* @return*/public static Date getSqMonthLastDate(Date date, Integer sq){Calendar curCal = Calendar.getInstance();curCal.setTime(date);curCal.add(Calendar.MONTH, sq);curCal.set(Calendar.DATE, 1);  curCal.roll(Calendar.DATE, - 1);  return curCal.getTime();}/*** 获取一个月以前* @return*/public static Date getMonthBefore(){return DateUtil.getNDatesBefore(-30);}/*** 获取多少天之前* n为正数是,表示多少天后* 负数时,表示多少天前* @param n* @return*/public static Date getNDatesBefore(Integer n){Calendar curCal = Calendar.getInstance();curCal.add(Calendar.DATE, n);return curCal.getTime();}public Integer getMonthWeekCount(Date date){Calendar c = Calendar.getInstance();int week = c.get(Calendar.WEEK_OF_MONTH);//获取是本月的第几周return week;}/*** 给任意一个日期,输出当周的周一* 周日要回退几天* @return*/public static Date getMonday(Date date) {Calendar curCal = Calendar.getInstance();curCal.setTime(date);int week  = curCal.get(Calendar.DAY_OF_WEEK);//周日的话回退几天,找周一if(week == Calendar.SUNDAY)curCal.add(Calendar.DATE, -3);curCal.set(Calendar.DAY_OF_WEEK,Calendar.MONDAY);return curCal.getTime();   }public static void main(String[] args) {     System.out.println(DateUtil.getTimestamp("yyyyMMdd"));String str=DateUtil.formatDate(DateUtil.add(new Date(), Calendar.DAY_OF_YEAR, -30));System.out.println(str);}}

package com.enation.app.shop.core.utils;import java.io.Serializable;public class IpInfo implements Serializable {private static final long serialVersionUID = 1L;private String region;// 省private String city;// 市private String county;// 区private String isp;// ISP公司private String citySimpleName;// 市级简称public IpInfo() {super();}public IpInfo(String region, String city) {super();this.region = region;this.city = city;}public IpInfo(String region, String city, String county) {super();this.region = region;this.city = city;this.county = county;}public String getRegion() {return region;}public void setRegion(String region) {this.region = region;}public String getCity() {return city;}public void setCity(String city) {this.city = city;}public String getCounty() {return county;}public void setCounty(String county) {this.county = county;}public String getIsp() {return isp;}public void setIsp(String isp) {this.isp = isp;}public String getCitySimpleName() {if (city != null) {citySimpleName = city.replace("市", "").replace("地区", "");}return citySimpleName;}public void setCitySimpleName(String citySimpleName) {this.citySimpleName = citySimpleName;}}

package com.enation.app.shop.core.utils;import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.SocketTimeoutException;
import java.net.URL;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;public class IpUtils {/*** 获得用户远程地址*/public static String getRemoteAddr(HttpServletRequest request) {String remoteAddr = request.getHeader("X-Real-IP");if (StringUtils.isNotBlank(remoteAddr)) {remoteAddr = request.getHeader("X-Forwarded-For");} else if (StringUtils.isNotBlank(remoteAddr)) {remoteAddr = request.getHeader("Proxy-Client-IP");} else if (StringUtils.isNotBlank(remoteAddr)) {remoteAddr = request.getHeader("WL-Proxy-Client-IP");}return remoteAddr != null ? remoteAddr : request.getRemoteAddr();}public static void main(String[] args) {String ip = "183.58.24.176";try {IpInfo ipInfo = IpUtils.getIpInfo(ip);
//          System.out.println(ipInfo.getRegion() + ipInfo.getCity()
//                  + ipInfo.getCounty() + "   " + ipInfo.getIsp());System.out.println(ipInfo.getCity()+ ipInfo.getCounty() );} catch (Exception e) {e.printStackTrace();}}public static IpInfo getIpInfo(HttpServletRequest request) {String ip = getRemoteAddr(request);IpInfo ipInfo = getIpInfo(ip);if (ipInfo == null || StringUtils.isBlank(ipInfo.getCity())) {ipInfo = new IpInfo();}System.out.println("访问ip:" + ip + "  " + ipInfo.getRegion()+ ipInfo.getCity() + ipInfo.getCounty() + "   "+ ipInfo.getIsp());return ipInfo;}/*** 获取地址* * @param ip* @param encoding* @return* @throws Exception*/public static IpInfo getIpInfo(String ip) {String path = "http://ip.taobao.com/service/getIpInfo.php";String params = "ip=" + ip;String returnStr = doGet(path, params, "utf-8");if (returnStr != null) {Gson gson = new Gson();JsonParser parser = new JsonParser();JsonObject json = parser.parse(returnStr).getAsJsonObject();if ("0".equals(json.get("code").toString())) {return gson.fromJson(json.get("data"), IpInfo.class);}}return null;}/*** 从url获取结果* * @param path* @param params* @param encoding* @return*/public static String doGet(String path, String params, String encoding) {URL url = null;HttpURLConnection connection = null;try {url = new URL(path);connection = (HttpURLConnection) url.openConnection();// 新建连接实例connection.setConnectTimeout(2000);// 设置连接超时时间,单位毫秒connection.setReadTimeout(2000);// 设置读取数据超时时间,单位毫秒connection.setDoInput(true);// 是否打开输入流true|falseconnection.setDoOutput(true);// 是否打开输出流true|falseconnection.setRequestMethod("GET");// 提交方法POST|GETconnection.setUseCaches(false);// 是否缓存true|falseconnection.connect();// 打开连接端口DataOutputStream out = new DataOutputStream(connection.getOutputStream());out.writeBytes(params);out.flush();out.close();BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), encoding));StringBuffer buffer = new StringBuffer();String line = "";while ((line = reader.readLine()) != null) {buffer.append(line);}reader.close();return buffer.toString();} catch (SocketTimeoutException socketTimeoutException) {return null;} catch (Exception e) {e.printStackTrace();} finally {if (connection != null) {connection.disconnect();// 关闭连接}}return null;}}

html页面

var opentime;//打开页面的时间
var closetime;//关闭页面的时间
Date.prototype.Format = function (fmt) { //author: meizz var o = {"M+": this.getMonth() + 1, //月份 "d+": this.getDate(), //日 "h+": this.getHours(), //小时 "m+": this.getMinutes(), //分 "s+": this.getSeconds(), //秒 "q+": Math.floor((this.getMonth() + 3) / 3), //季度 "S": this.getMilliseconds() //毫秒 };if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));for (var k in o)if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));return fmt;
}function checkLeave(){ closetime = new Date().Format("yyyy-MM-dd hh:mm:ss");  var html=window.location.href;/*  event.returnValue="确定离开当前页面吗?"+html;  */
$.ajax({url:"${ctx}/api/shop/logtime!addLogtime.do?ajax=yes",dataType:"json",cache: true,data:{opentime:opentime,closetime:closetime,html:html},success:function(result){if(result.result==1){}else{/* layer.msg("出错了", { icon: 7,time: 2000 }, function(){});  */}    /* layer.close(index);  */},error:function(){/* layer.close(index);  *//* layer.msg("出错了:(", { icon: 7,time: 2000 }, function(){});  */}
});
}$(function(){opentime = new Date().Format("yyyy-MM-dd hh:mm:ss");  });

  

转载于:https://www.cnblogs.com/nbkyzms/p/5116459.html

用户日志留存所采用的技术手段相关推荐

  1. 淘宝十年资深架构师吐血总结淘宝的数据库架构设计和采用的技术手段。

    淘宝十年资深架构师吐血总结淘宝的数据库架构设计和采用的技术手段. 文章目录 淘宝十年资深架构师吐血总结淘宝的数据库架构设计和采用的技术手段. 本文导读 1.分库分表 2.数据冗余 3.异步复制 4.读 ...

  2. 上网日志留存_互联网用户日志留存技术标准

    项目 序号(与 检查笔录 依据和罚则 检查内容 检查方法 检查标准(黑色粗体字表示非强制要求) 序 号对 应 ) ( 1 )依据 记录并留存 用户 ( 1 )注册信息 ( 1 )注册信息 <互联 ...

  3. 电信业务经营许可证申请办事指南

    申请材料 申请办理增值电信业务经营许可证的所有申报材料及流程均线上完成,上传系统准备材料如下: (一)增值电信业务经营许可证申请表.内容包括:申请经营电信业务的种类.业务覆盖范围.公司名称.营业执照, ...

  4. 如何写一个包含多个事件四则运算的留存SQL ——impala hive

    在实现一个留存业务需求时,碰到了一个难题,我需要提供展示一个按照如下图格式的数据, day 1 ~ day n的第一行是留存用户数量,第二行是一个由多个事件组合执行四则算术运算得到的复合数值,这里碰到 ...

  5. 重磅!银保监此文一出,商业银行采用电子合同势在必行

    据银保监会官网5月9日消息,规范商业银行互联网贷款业务经营行为,促进互联网贷款业务平稳健康发展,银保监会起草了<商业银行互联网贷款管理暂行办法(征求意见稿)>(下称<办法>). ...

  6. 深度 | 推荐系统评估

    作者 | gongyouliu 来源 | 大数据工程师 作者在上篇文章<推荐系统的工程实现>中提到推荐系统要很好地落地到业务中,需要搭建支撑模块,其中效果评估模块就是其中非常重要的一个.本 ...

  7. hadoop三个配置文件的参数含义说明

    1       获取默认配置 配置hadoop,主要是配置core-site.xml,hdfs-site.xml,mapred-site.xml三个配置文件,默认下来,这些配置文件都是空的,所以很难知 ...

  8. hadoop配置文件默认配置

    原文地址:http://www.linuxqq.net/archives/964.html 获取默认配置 配置hadoop,主要是配置core-site.xml,hdfs-site.xml,mapre ...

  9. 推荐系统评估:你的推荐系统足够好吗?

    本篇作者主要从"什么是一个好的推荐系统"."在推荐系统业务的各个阶段怎么评估推荐系统","推荐系统怎么更好地满足用户的诉求"的角度来讲解.我 ...

最新文章

  1. org.quartz-scheduler 基础过程
  2. 代理模式、动态代理和面向方面
  3. python 生成html表的报告_pytest文档7-pytest-html生成html报告
  4. 机器学习笔记九之支持向量机
  5. python gil锁_python--GIL锁
  6. CentOS下配置apache+gitweb
  7. 漂亮的消息通知html邮件模板,好看的邮件模板?
  8. XRHT系列电钢琴实训室配置方案及清单
  9. activiti6.0通过bpmn.js展示高亮流程图(前端绘制流程图)
  10. Ubuntu18.04笔记本触控板失效解决办法
  11. 金融衍生品数据分析_大数据_numpy,matplotlib,pandas学习
  12. mysql中没有sock文件_mysql.sock文件不见了问题的解决方法
  13. 前端用ps创建画布的分辨率应该设置的值
  14. confluence插入目录
  15. 飞思卡尔芯片k66单片机溢出_PWM 初试溢出中断
  16. 什么是Bom,常用的bom属性又有哪些?
  17. easyexcel导入时读不到数据_EasyExcel快速读写Excel数据
  18. JAVA面试题整理2020
  19. 华为鸿蒙电池,4700mAh电池+新鸿蒙系统华为Mate40,华为Mate30再创超低价神话
  20. 概率论与数理统计学习笔记——第13讲——依概率收敛的意义

热门文章

  1. Exchange 2007 安裝(-)
  2. GARFIELD@04-14-2005
  3. ubuntu每日构建版
  4. Flink EventTime和Watermarks原理结合代码分析(转载+解决+精简记录)
  5. 第一、第二、第三范式之间的理解和比较(转载)
  6. 使用K-S检验一个数列是否服从正态分布、两个数列是否服从相同的分布(转载+自己笔记)
  7. win7内部版本7601副本不是正版
  8. 凸优化函数的一些概念(转)
  9. 平方环法_2019环法挑战赛加速诸暨“运动之城”建设 推动“体育+旅游”新热潮...
  10. AndroidAnnotations开发框架在Eclipse中的搭建和使用以及框架实现的原理