Explorar o código

课程学习人数计算;api接口日志切面

yangfeng hai 1 ano
pai
achega
496c0f4784

+ 46 - 0
web/src/main/java/com/ynfy/app/api/v1/annoation/ApiLog.java

@@ -0,0 +1,46 @@
+package com.ynfy.app.api.v1.annoation;
+
+import org.jeecg.common.constant.CommonConstant;
+import org.jeecg.common.constant.enums.ModuleType;
+
+import java.lang.annotation.*;
+
+/**
+ * 系统日志注解
+ * 
+ * @Author scott
+ * @email jeecgos@163.com
+ * @Date 2019年1月14日
+ */
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface ApiLog {
+
+	/**
+	 * 日志内容
+	 * 
+	 * @return
+	 */
+	String value() default "";
+
+	/**
+	 * 日志类型
+	 * 
+	 * @return 0:操作日志;1:登录日志;2:定时任务;
+	 */
+	int logType() default CommonConstant.LOG_TYPE_2;
+	
+	/**
+	 * 操作日志类型
+	 * 
+	 * @return (1查询,2添加,3修改,4删除)
+	 */
+	int operateType() default 0;
+
+	/**
+	 * 模块类型 默认为common
+	 * @return
+	 */
+	ModuleType module() default ModuleType.COMMON;
+}

+ 264 - 0
web/src/main/java/com/ynfy/app/api/v1/aspect/ApiLogAspect.java

@@ -0,0 +1,264 @@
+package com.ynfy.app.api.v1.aspect;
+
+import com.alibaba.fastjson.JSONObject;
+import com.alibaba.fastjson.serializer.PropertyFilter;
+import org.aspectj.lang.JoinPoint;
+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.aspectj.lang.reflect.MethodSignature;
+import org.jeecg.common.api.dto.LogDTO;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.aspect.annotation.AutoLog;
+import org.jeecg.common.constant.CommonConstant;
+import org.jeecg.common.constant.enums.ModuleType;
+import org.jeecg.common.constant.enums.OperateTypeEnum;
+import org.jeecg.common.system.vo.LoginUser;
+import org.jeecg.common.util.IpUtils;
+import org.jeecg.common.util.SpringContextUtils;
+import org.jeecg.common.util.TokenUtil;
+import org.jeecg.common.util.oConvertUtils;
+import org.jeecg.modules.base.service.BaseCommonService;
+import org.jeecg.modules.system.service.ISysUserService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
+import org.springframework.stereotype.Component;
+import org.springframework.validation.BindingResult;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.annotation.Resource;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
+import java.lang.reflect.Method;
+import java.util.Date;
+import java.util.Objects;
+
+
+/**
+ * 移动端api日志,切面处理类
+ */
+@Aspect
+@Component
+public class ApiLogAspect {
+
+    @Resource
+    private BaseCommonService baseCommonService;
+
+    @Autowired
+    private ISysUserService sysUserService;
+
+    @Pointcut("@annotation(com.ynfy.app.api.v1.annoation.ApiLog)")
+    public void logPointCut() {
+
+    }
+
+    @Around("logPointCut()")
+    public Object around(ProceedingJoinPoint point) throws Throwable {
+        long beginTime = System.currentTimeMillis();
+        //执行方法
+        Object result = point.proceed();
+        //执行时长(毫秒)
+        long time = System.currentTimeMillis() - beginTime;
+
+        //保存日志
+        saveSysLog(point, time, result);
+
+        return result;
+    }
+
+    private void saveSysLog(ProceedingJoinPoint joinPoint, long time, Object obj) {
+        //获取request
+        HttpServletRequest request = SpringContextUtils.getHttpServletRequest();
+
+        //获取登录用户信息
+        LoginUser sysUser = sysUserService.getLoginUser(TokenUtil.getToken(request));
+        if (Objects.isNull(sysUser)) {
+            return;
+        }
+        LogDTO dto = new LogDTO();
+        dto.setUserid(sysUser.getUsername());
+        dto.setUsername(sysUser.getRealname());
+
+        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
+        Method method = signature.getMethod();
+
+
+        AutoLog syslog = method.getAnnotation(AutoLog.class);
+        if (syslog != null) {
+            //update-begin-author:taoyan date:
+            String content = syslog.value();
+            if (syslog.module() == ModuleType.ONLINE) {
+                content = getOnlineLogContent(obj, content);
+            }
+            //注解上的描述,操作日志内容
+            dto.setLogType(syslog.logType());
+            dto.setLogContent(content);
+        }
+
+        //请求的方法名
+        String className = joinPoint.getTarget().getClass().getName();
+        String methodName = signature.getName();
+        dto.setMethod(className + "." + methodName + "()");
+
+
+        //设置操作类型
+        if (CommonConstant.LOG_TYPE_2 == dto.getLogType()) {
+            dto.setOperateType(getOperateType(methodName, syslog.operateType()));
+        }
+
+        //请求的参数
+        dto.setRequestParam(getReqestParams(request, joinPoint));
+        //设置IP地址
+        dto.setIp(IpUtils.getIpAddr(request));
+
+        //耗时
+        dto.setCostTime(time);
+        dto.setCreateTime(new Date());
+        //保存系统日志
+        baseCommonService.addLog(dto);
+    }
+
+
+    /**
+     * 获取操作类型
+     */
+    private int getOperateType(String methodName, int operateType) {
+        if (operateType > 0) {
+            return operateType;
+        }
+        //update-begin---author:wangshuai ---date:20220331  for:阿里云代码扫描规范(不允许任何魔法值出现在代码中)------------
+        return OperateTypeEnum.getTypeByMethodName(methodName);
+        //update-end---author:wangshuai ---date:20220331  for:阿里云代码扫描规范(不允许任何魔法值出现在代码中)------------
+    }
+
+    /**
+     * @param request:   request
+     * @param joinPoint: joinPoint
+     * @Description: 获取请求参数
+     * @author: scott
+     * @date: 2020/4/16 0:10
+     * @Return: java.lang.String
+     */
+    private String getReqestParams(HttpServletRequest request, JoinPoint joinPoint) {
+        String httpMethod = request.getMethod();
+        String params = "";
+        if (CommonConstant.HTTP_POST.equals(httpMethod) || CommonConstant.HTTP_PUT.equals(httpMethod) || CommonConstant.HTTP_PATCH.equals(httpMethod)) {
+            Object[] paramsArray = joinPoint.getArgs();
+            // java.lang.IllegalStateException: It is illegal to call this method if the current request is not in asynchronous mode (i.e. isAsyncStarted() returns false)
+            //  https://my.oschina.net/mengzhang6/blog/2395893
+            Object[] arguments = new Object[paramsArray.length];
+            for (int i = 0; i < paramsArray.length; i++) {
+                if (paramsArray[i] instanceof BindingResult || paramsArray[i] instanceof ServletRequest || paramsArray[i] instanceof ServletResponse || paramsArray[i] instanceof MultipartFile) {
+                    //ServletRequest不能序列化,从入参里排除,否则报异常:java.lang.IllegalStateException: It is illegal to call this method if the current request is not in asynchronous mode (i.e. isAsyncStarted() returns false)
+                    //ServletResponse不能序列化 从入参里排除,否则报异常:java.lang.IllegalStateException: getOutputStream() has already been called for this response
+                    continue;
+                }
+                arguments[i] = paramsArray[i];
+            }
+            //update-begin-author:taoyan date:20200724 for:日志数据太长的直接过滤掉
+            PropertyFilter profilter = new PropertyFilter() {
+                @Override
+                public boolean apply(Object o, String name, Object value) {
+                    int length = 500;
+                    if (value != null && value.toString().length() > length) {
+                        return false;
+                    }
+                    return true;
+                }
+            };
+            params = JSONObject.toJSONString(arguments, profilter);
+            //update-end-author:taoyan date:20200724 for:日志数据太长的直接过滤掉
+        } else {
+            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
+            Method method = signature.getMethod();
+            // 请求的方法参数值
+            Object[] args = joinPoint.getArgs();
+            // 请求的方法参数名称
+            LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer();
+            String[] paramNames = u.getParameterNames(method);
+            if (args != null && paramNames != null) {
+                for (int i = 0; i < args.length; i++) {
+                    params += "  " + paramNames[i] + ": " + args[i];
+                }
+            }
+        }
+        return params;
+    }
+
+    /**
+     * online日志内容拼接
+     *
+     * @param obj
+     * @param content
+     * @return
+     */
+    private String getOnlineLogContent(Object obj, String content) {
+        if (Result.class.isInstance(obj)) {
+            Result res = (Result) obj;
+            String msg = res.getMessage();
+            String tableName = res.getOnlTable();
+            if (oConvertUtils.isNotEmpty(tableName)) {
+                content += ",表名:" + tableName;
+            }
+            if (res.isSuccess()) {
+                content += "," + (oConvertUtils.isEmpty(msg) ? "操作成功" : msg);
+            } else {
+                content += "," + (oConvertUtils.isEmpty(msg) ? "操作失败" : msg);
+            }
+        }
+        return content;
+    }
+
+
+    /*    private void saveSysLog(ProceedingJoinPoint joinPoint, long time, Object obj) {
+        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
+        Method method = signature.getMethod();
+
+        SysLog sysLog = new SysLog();
+        AutoLog syslog = method.getAnnotation(AutoLog.class);
+        if(syslog != null){
+            //update-begin-author:taoyan date:
+            String content = syslog.value();
+            if(syslog.module()== ModuleType.ONLINE){
+                content = getOnlineLogContent(obj, content);
+            }
+            //注解上的描述,操作日志内容
+            sysLog.setLogContent(content);
+            sysLog.setLogType(syslog.logType());
+        }
+
+        //请求的方法名
+        String className = joinPoint.getTarget().getClass().getName();
+        String methodName = signature.getName();
+        sysLog.setMethod(className + "." + methodName + "()");
+
+
+        //设置操作类型
+        if (sysLog.getLogType() == CommonConstant.LOG_TYPE_2) {
+            sysLog.setOperateType(getOperateType(methodName, syslog.operateType()));
+        }
+
+        //获取request
+        HttpServletRequest request = SpringContextUtils.getHttpServletRequest();
+        //请求的参数
+        sysLog.setRequestParam(getReqestParams(request,joinPoint));
+
+        //设置IP地址
+        sysLog.setIp(IPUtils.getIpAddr(request));
+
+        //获取登录用户信息
+        LoginUser sysUser = (LoginUser)SecurityUtils.getSubject().getPrincipal();
+        if(sysUser!=null){
+            sysLog.setUserid(sysUser.getUsername());
+            sysLog.setUsername(sysUser.getRealname());
+
+        }
+        //耗时
+        sysLog.setCostTime(time);
+        sysLog.setCreateTime(new Date());
+        //保存系统日志
+        sysLogService.save(sysLog);
+    }*/
+}

+ 1 - 0
web/src/main/java/com/ynfy/app/api/v1/controller/ApiAuthController.java

@@ -219,6 +219,7 @@ public class ApiAuthController {
         result.setResult(obj);
         result.setSuccess(true);
         result.setCode(200);
+        baseCommonService.addLog("用户名: " + wxUser.getUsername() + ",微信登录成功!", CommonConstant.LOG_TYPE_1, null);
         return result;
     }
 

+ 6 - 7
web/src/main/java/com/ynfy/buss/course/course/entity/Course.java

@@ -150,13 +150,6 @@ public class Course implements Serializable {
     @ApiModelProperty(value = "学员")
     private String learner;
 
-    /**
-     * 学习人数
-     */
-    @Excel(name = "学习人数", width = 15)
-    @ApiModelProperty(value = "学习人数")
-    private Integer learnerNumber;
-
     /**
      * 离开多少分钟弹窗
      */
@@ -261,4 +254,10 @@ public class Course implements Serializable {
      */
     @TableField(exist = false)
     private Double courseStudyProcess;
+
+    /**
+     * 学习人数
+     */
+    @TableField(exist = false)
+    private Integer learnerNumber;
 }

+ 16 - 1
web/src/main/java/com/ynfy/buss/course/course/mapper/xml/CourseMapper.xml

@@ -4,7 +4,8 @@
     <select id="selectCourseList"  resultType="com.ynfy.buss.course.course.entity.Course">
         SELECT
                 tmp1.*,
-                u.realname AS teacherName
+                u.realname AS teacherName,
+                tmp2.learner_number
         FROM
         (
             SELECT
@@ -34,6 +35,20 @@
             </when>
         </choose>
         ) tmp1
+        LEFT JOIN
+        (
+            SELECT
+                cc.course_id,
+                count(
+                DISTINCT (ucc.user_id)) AS learner_number
+            FROM
+                user_course_catalog ucc
+            LEFT JOIN
+                course_catalog cc ON ucc.course_catalog_id = cc.id
+            GROUP BY
+                    cc.course_id
+        ) tmp2
+        ON tmp1.id = tmp2.course_id
         LEFT JOIN sys_user u on tmp1.teacher_id=u.id
         <where>
             <if test="course.name!=null and course.name!=''">